Saying "it's not the most elegant language" is quite (mis)leading. While I would not claim that it is the most elegant language, I would most definitely claim that it is elegant.
Two things that many people get wrong about JavaScript: (1.) Most of the ugly parts involve interacting with the DOM, and the DOM is NOT JavaScript, and (2.) Just because some people write ugly code with it does not mean that the language itself is ugly.
ES6 and ES7 have done wonders for the language syntax, and the flexibility of the language allows you to write in any combination of procedural, functional, prototypical, object-oriented programming styles. I mix them together as needed to make programs more intuitive and easier to follow. Programming is an art, and JavaScript is a powerful and versatile tool.
You are also wrong in that it being the only language supported by browsers. That may be the case now, but in the past many, many, many websites used flash and java applets. Quite frankly, the reason that JavaScript is what we have now is because it really is that good that it replaced all the other options.
All of the other questions are all over the board... It sounds like you are trying to get us to write a homework assignment for you.
I haven't looked at ES6/7, and its true that any language in the wrong hands can be ugly. But there's a lot wrong with JS besides how it interfaces with the DOM[1]. Which is funny because it was originally conceived as a browser scripting language[2].
And JS beating flash and java applets may be more a result of market forces (Apple) and the lack of better alternatives.
Brendan Eich designed JS in 10 days for the early era of the web, which is very different today. Its both a testament to the language and the hacks on top of it that its stayed in use this long. But maybe its time to move on?
This can get a little confusing until you understand how context works. Then it makes sense but you know what? You don't always need to use this. In fact you can build entire applications in different ways without ever using this. And no writing without using this doesn't make your code ugly or unmanageable. There are just many ways to get the same or similar things done in JavaScript.
> type coercion in JS
Type coercion is ugly in any programming language. It's best to avoid it, even in JavaScript (which you can do, btw).
Sure but this problem is inherent to any dynamic language. I find other issues far worse than simple type coercion. What about calling a function? Most dynamic languages will let you pass in any number of parameters regardless of its definition and you may not even notice.
You can avoid type coercion if you understand how the language works (aka strict equality in JavaScript) but this isn't something only in JavaScript land either.
There are two separate issues in play here. You're conflating the static/dynamic dimension of language classification with the strongly-/loosely-typed dimension of languages which is what the poster you are responding to was talking about [1]. These two dimensions are orthogonal: languages may be static, but weakly typed (like C), or dynamic but strongly typed (like Python).
I'll allow that there's inevitably some degree of opinion involved here, but I tend to agree with the parent poster that implicit conversion in languages like Javascript, PHP, and Perl is just another vector for bugs, and outweighs any of the advantages you get from having your language coerce everything for you. But then again, i'm one of those people that likes my language to force me to be very explicit about what I mean, so YMMV.
Regardless, the strict equality operator is not at all sufficient to avoid the dangers of JavaScript's implicit conversions. Pretty much _all_ the operators are going to coerce types for you, whether you meant for them to or not. For example, this function:
function increment(i) { return i + 1; }
Adds one to number right? But let’s say you’ve neglected to convert some user input in a form to a number as you should have done elsewhere in your code, and you end up calling increment("1"). This will return "11". So now you potentially have introduced a serious math error into your code you may not notice right away. Conversely, if you did this in Python, the function would have raised a TypeError immediately, because you can’t apply the arithmetic operator to two different types. You can’t just “avoid” type coercion in these loosely-typed languages by understanding the specifics of how it works, because you may not even know it’s happening until you start seeing unexpected results somewhere.
> Most dynamic languages will let you pass in any number of parameters regardless of its definition and you may not even notice.
Python will throw an error. Ruby will throw an error. Tcl will throw an error.
Erlang will throw an error. I believe most of the Lisps will throw an error.
I should have changed my text to not say "regardless of definition" because you can do that in Python, Ruby, PHP, JavaScript, etc.
Python and Ruby support it through (star)args or default parameters
JavaScript supports it regardless
PHP supports it regardless
We can argue semantics or the fact that some of those types of errors can be caught with some subset of dynamic languages but I don't think that's useful.
My only point was when comparing a dynamic language with a static language I find variable function parameters to be one of the bigger issues over type coercion. But that's just, like, my opinion.
Those aren't particular to dynamic languages, though. You can add C, C++, Java, and C# to your list of languages that support it. Being able to explicitly make a parameter optional, or to have a 0-or-more rest argument is different from how function application works in Javascript or Perl because you have explicitly made that part of your function's signature, and the language still checks calls against that signature.
Could you please explain? It's always very clear in Python what `self` refers to. Self is always an instance of the parent object of a method. Some classes can also have static class methods that can be called from the class itself instead of one of it's instances. Maybe that is where your confusion is arising?
It's not that it's confusing, rather it's unnecesarrely cumbersome because it's explicit and because you have to put it as an argument. Looking at the "most used words" [1] list of python, self is the #1 used word by far, occuring three times as often as the second most common word, "if". At this point, it's just a filler that bloats code and makes it less readable in many cases
# so much text for such a little task
def length(self):
return math.sqrt(self.x*self.x + self.y*self.y + self.z*self.z)
# better, but not quite there yet
def length(self):
return math.sqrt(self.x**2 + self.y**2 + self.z**2)
# this would be perfect, but it's not allowed by python
def length():
return math.sqrt(x*x + y*y + z*z)
To be fair, javascript also forces you to explicitly specify "this" so there is no difference in that regard.
What I find worse than that is that you have to specify self in the parameter list.
Calling a function with 2 parameters but having to declare 3 doesn't make sense. The usuall reasoning is that "explit is always better than implicit" but I do not agree. We could take this philosophy all the way to explicitly defining all the global variables that may be used by the function in the parameter list, maybe even all the packages that this function is going to use. We don't do that for a good reason.
Saying it's unnecessary is incorrect, and I don't agree about it being cumbersome either. On the first point, how would you disambiguate between reading from an attribute and reading from a global (or non-local) variable? How would you disambiguate between assigning to a variable and assigning to an attribute? You'd have to explicitly declare all your variables (making other things cumbersome instead) or accept that the semantics of your program could change during run time, depending on the contents of outer scopes (which I doubt you'd find an acceptable option). This is the main reason the 'with' statement is deprecated in JS. C++ can get away with implicit 'this' because it has static dispatch and all variables are explicitly declared anyway. But truth be told, I'd remove it from C++ too if I could. I like the clarity of knowing at call site whether something is a function or a method call without having to look it up. Paying for it the price of having type a few more characters has never bothered me.
And I somewhat like that I can name my 'self' argument whatever I like instead of having to resort to obtuse workarounds like 'var that = this;'. Not that I've ever had the need to take advantage of that possibility in Python, but it's comforting to know it's there.
In a short function that makes a lot of references to self, yeah I agree in can be a bit cumbersome. But as the functions get longer, I much prefer the explicit use of self. It makes the code far more readable as you can tell at a glance where a variable comes from.
> It's not that it's confusing, rather it's unnecesarrely cumbersome because it's explicit and because you have to put it as an argument.
I don't feel the same way. To each their own I guess.
Regarding your example, I don't see anything wrong with the second version. Anyone who reads the code will easily be able to tell what it does and where the variables come from. In your third example, how is anyone supposed to know whether or not `x`, `y`, and `z` are class variables or global variables? Kind of defeats the purpose of namespacing, I think.
> What I find worse than that is that you have to specify self in the parameter list.
This is really one of Python's implementation details. Methods can be bound or unbound. Without going into to much detail, just know that a bound method can be used as a regular function. Here is some code to illustrate what I mean:
>>> class A():
... def a(self):
... print('hello')
...
>>> A
<class '__main__.A'>
>>> A.a
<function A.a at 0x7fc4009381e0>
>>> A.a()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: a() missing 1 required positional argument: 'self'
>>> A().a()
hello
>>> b = A()
>>> A.a(b)
hello
>>> class B():
... pass
...
>>> b = B()
>>> A.a(b)
hello
>>> class B():
... def a(self):
... print('goodbye')
...
>>> b = B()
>>> A.a(b)
hello
>>> c = A()
>>> B.a(c)
goodbye
Self does not have to be the same class it's called on. It can be any class. However, if you try to access a class attribute that doesn't exist, you get an attribute error.
>>> class C():
... x = 10
... def a(self):
... print(self.x)
...
>>> C.a()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: a() missing 1 required positional argument: 'self'
>>> C().a()
10
>>> a = A()
>>> a.a()
hello
>>> C.a(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in a
AttributeError: 'A' object has no attribute 'x'
Since bound methods need to behave like regular functions, it is improper to not pass the object instance to the function.
What do you mean? Could you give an example?
I always regarded python self to be one of the cleanest ways to show that we have another parameter in a method.
are you joking, right?
in javascript you cannot ever KNOW what this refers to (is the instance of a new Thing()? is null? is "window"? is something set with .bind()? is just "the left thing before the dot before the function"? is something else?
Eh. Python and JavaScript are very similar at the language level. They each have warts and are more expressive in certain areas, but at a high level they have the same semantics and the exact same advantages and disadvantages.
this is only used with the new keyword. You can however program JS avoiding both new, prototype and this, by using "factory functions". Or avoid OOP structures altogether using a more functional paradigm.
If the new keyword is not used, "this" will point to the global scope. You do not however have to use the new keyword when creating the built in JS objects.
{} is new Object();
If you find "this" confusing you can and should avoid using it.
JavaScript has many bad parts that some programmers love to use because it makes their code "elegant". It is however possible to write simple and easy to understand code by only using the good parts.
>>If the new keyword is not used, "this" will point to the global scope
This is entirely incorrect information, consider a simple example:
function f(){console.log(this.a);}
var o={a:"c"}
f.call(o)
there is no "new" keyword involved, and "this" is not pointing to the global scope and there is a huge amount of other samples which I can show, but I won't. I don't have any problems with understanding "this" in JS. I just firmly believe that this is superb ugly stuff.
I don't think it's a good solution because it performs the operation manually instead of calling the built-in Math.hypot method. This is the point - "apply" is a widely used technique, at least it used to be on pre-ES6 times.
JavaScript is as elegant as a cat scratching his nails on a blackboard.
it's a mongrel language without any whatsoever elegance.
Taking your art metaphor further is like comparing the ceiling of the "cappella sistina" to a cut in a canvas.
3) Maybe a language don't need to be that "elegant", it's not required in all situations. I think I would prefer a "practical" language over "elegance" but like the appearance.
Two things that many people get wrong about JavaScript: (1.) Most of the ugly parts involve interacting with the DOM, and the DOM is NOT JavaScript, and (2.) Just because some people write ugly code with it does not mean that the language itself is ugly.
ES6 and ES7 have done wonders for the language syntax, and the flexibility of the language allows you to write in any combination of procedural, functional, prototypical, object-oriented programming styles. I mix them together as needed to make programs more intuitive and easier to follow. Programming is an art, and JavaScript is a powerful and versatile tool.
You are also wrong in that it being the only language supported by browsers. That may be the case now, but in the past many, many, many websites used flash and java applets. Quite frankly, the reason that JavaScript is what we have now is because it really is that good that it replaced all the other options.
All of the other questions are all over the board... It sounds like you are trying to get us to write a homework assignment for you.