Change the JS Function Tutorials


#1

I am a beginner, so please excuse and correct any mistakes I have made.

When I first started learning JavaScript on Codecademy, I was confused by the syntax for defining functions.
var funcName = function (argList)
{
def;
}

I thought, "Functions are not variables!" However, I recently learned about first-class functions, where a function can be assigned to a variable. I also searched up "JS Function Syntax," and found out that they are defined like this:
function funcName(argList)
{
def;
}

Why is Codecademy teaching first-class function assignment as a standard way to define functions to people who potentially may not have had prior exposure to functions, rather than the more basic way? If you're going to teach the former way, at least explain first-class citizens, please!


33/33 Methods
#2

Neither is a first-class functions, there is no such thing.

Functions are first-class citizens in JavaScript: https://en.wikipedia.org/wiki/First-class_function

The main difference is that the second one is defined globally, which is often not desirable.
A second difference is that the second one will have its name attribute set to "funcName", whereas the first gets "" as its name.

Edit: no, function declarations are not global, I was wrong.
Functions created with function declarations are hoisted, which means that JS reads the file and creates all declared functions before it starts executing the code in that scope. For example, this prints 5:

f();
function f() { console.log(5); }

Note that f is called earlier in the file than where the function is declared. This works because the declaration is read before executing the first line.


#3

I apologize for using the wrong terminology. Why is the Wikipedia article titled "First-Class function," though, if first-class functions don't exist?

Which version do tutorials and lessons usually teach? Should Codecademy explain anonymous functions in its JS function lessons?


#4

In computer science, a programming language is said to have first-class functions if it treats functions as first-class citizens.

It's about how a function is treated in a language, not what it is.

I suppose a language could be imagined that has two kinds of functions that are treated differently, but that's not how it goes in JS.

As for what/how Codecademy teaches, it certainly isn't correctness or rigour. It's more of a "get spoon-fed with digestible exercises" kind of deal.

Teaching programming correctly from the beginning can get really complicated and is much more difficult, it's so much easier if certain aspects are just ignored until later. That said, things could be better.


#5

So, is the term "first-class function" used to describe functions which are first-class citizens?

Would you recommend teaching the basic, but more unwise way of defining functions, or the more complicated way and potentially confuse learners with first-class citizens? I, personally, was actually confused because of the lack of explanation, though, because I didn't understand why a function was being assigned to a variable at the time.


#6

I should probably mention that I don't really know JS.

Educting myself on the topic right now!

Apparently another difference is that function declarations are run before any other code, whereas creating them with the function operator is something that's done when execution reaches that location.

While in the global scope, it won't make any difference, since the current scope is global anyhow, so that seems like a good balance, you wouldn't be saying something wrong.

Inside function var should definitely be used, functions should preferably only communicate with the scary outside world through its parameters and return values.

So if you then teach that var is used to create locals, then the clever folks might then figure out that this can be done with functions as well - or understand what's happening when they see it.

..Anyway, still googling. (and don't worry, this is just educational, time well spent)

@mtf how confident are you about this? I'm probably not fit to give any recommendations on teaching JS


#7

Not sure I could lead, but I could walk alongside. Let me wrap up what I'm doing and come back to this.

Moving to Corner Bar for open discussion. This Feature and Course Requests is on the back end people's watch list and they probably don't need to be notified every time someone posts to it.


#8

How often are functions created using the function operator in JavaScript? I am aware that many languages support functions as first-class citizens, but from my personal experience, lessons for those languages teach declarations when first introducing functions.


#9

Sounds very reasonable to me. Makes me wonder why they ever do anything different in the JS track.

The one argument that I (doesn't mean much) can come up with is that you might want to create a namespace for yourself to avoid polluting the global namespace (), and then one would have to use the operator.

If I open up my JS console on this page and look at the globals I have an immediate reaction of "can I please have my own namespace?". I don't know what a JS programmer would think about this.


#10

Would you say that JS doesn't have anything similar to Python modules? So that you've always got a clean slate when you start writing something and you know that nothing is going to interfere with it?

The best option is to create an object and put all ones stuff in it?

myNamespace = {
    anyNameIWant: function() {
    }
    ...
}

#11

Since JavaScript has only one namespace, the only guarantee that there will be no collisions is if everything is in a closure. There could be any number of plug-ins all swimming around in the one pool. Any variables that are in the global scope are visible to all of them.


#12

I wouldn't get too hung up on the first-class terminology. Just think of all JavaScript functions as being strings that can be executed. Well they are much more than that, but this is a general description.

In reality, they are object instances of the Function class, which is also an object instance of the Object class (which everything traces back to in JavaScript).

Functions like all objects have properties. Every function has a this and a return object, and every function has its own scope. this represents the execution context, and return can reach across from callee scope (local) to caller scope (elsewhere).

From Function.prototype, functions inherit call() and apply() which are able to change the execution context, but that's another discussion that's probably over both of our heads at the moment. Something to learn about down the road.

JavaScript uses a two pass approach to load and parse script. On the first pass it identifies scope and hoists all declared objects to the top of their scope. Any variable declarations that do not use var in the statement are hoisted to the top of global scope. Function declarations are hoisted in their entirety and are immutable. We cannot change them, or their name, and we cannot re-use the variable name deliberately or by accident.

Since declared functions are completely intact and loaded and ready on the first pass, it doesn't matter where they are written in the source code. They can be referred from above or below.

Variables are hoisted a little differently. Only their identifier is hoisted, not the value that they refer to. On the second pass, JavaScript completes their definition as it comes across the assignments. Values are mutable, variable names are not.

Functions written as an anonymous expression are actually just a string assignment given to a variable. Like values, these are replaceable.

Consider the following:

function g() {flag = false;}
function h() {flag = true;}
var flag, f;
do {
    f = flag ? g : h;
    f();
    console.log(flag);
} while (flag);

logs out,

true
false

We are able to toggle the function string on the fly while maintaining a single name for the function we invoke. This is very handy to be able to do.

Unlike declared functions, since expressions are not read until the second pass, these functions must be defined before any call to them can be made, so must appear above their first call in the source code.


#13

Are you saying that anonymous functions are compiled to a lesser degree than declared functions? My expectation from Python is that the function constructor would receive a string or perhaps a more efficient representation from the language's code parser, and compile it into the same kind of function as anything else, similar to Python's byte-code:

>>> ' '.join(c.encode('hex') for c in (lambda x: x + 5).func_code.co_code)
'7c 00 00 64 01 00 17 53'

(the equivalent def statement compiles to the same series of bytes)

Those are the bytes that Python's main-loop would read to execute the function object that the lambda expression creates. The first byte specifies a C function to run (LOAD_FAST for 0x7c), the next two bytes are an argument to LOAD_FAST and then comes another function LOAD_CONST and another two-byte argument, then BINARY_ADD (no arguments, uses values on stack) and the final byte, 0x53, is RETURN_VALUE

.. Sure it can be printed out, and a block of bytes is how strings are represented in C. But it's ready to be executed without having to parse anything, so string isn't the first way I would describe it.

So what's done to this string? Surely it's not the source code itself, even if that's kept or reconstructed by toString for the sake of inspecting it?


#14

Consider,

function foo(bar){
    return bar;
}
console.log(foo.toString());

Output

function foo(bar){
    return bar;
}

I'm not well versed on the parsing process, but as I understand it, there is no pre-compiling in JavaScript. Everything is transient, real-time script interpretation, line by line as it is being executed. There may be some caching, but it too is transient. The compiled code would have to take some form of byte code or tokenization in the final stage, but not the way Python or Ruby would do it, and definitely nothing like C or Java. As earlier stated, this may be way out to lunch.

JavaScript is very slow in comparison to the other languages, and we can see why. Statements are interpreted, compiled and executed one at a time, even in loops. So, as earlier suggested, functions remain the string they started out as.


#15

I'm quite sure Python is less compiled than JS. There's a high demand for fast JS interpreters since lots of people sit in front of their screen waiting for them to run. Python just has to be nice and have C modules available for the heavy lifting.

Both of them parse the code, then run it. JS takes it further and JIT's stuff when it gets the opportunity, starting with inner loops and the like

I'm not buying into this string thing, not at all!


#16

Notice that the example above is a hoisted function. It still can be rendered as a string representation of itself. With hoisted functions, that string object is ready and waiting on the shelf. When we assign an anonymous function, we are really assigning it within a string wrapper object. This would seem useful in keeping it all contiguous in memory.

It comes back to caching. My understanding is that JS is not big on caching native code and longer than it needs to. That means if the same bit of code is called again, it has to come off the shelf in its string form and be tokenized and interpreted anew. Now my lack of indepth knowledge shows big time, and I cannot confirm or refute that functions, once compiled don't take on a token form. For all we know they may, but I'm still doubtful.

Great information starting to surface. Thanks for that.

.Edit:


#17

This article helps to lift my doubts: http://creativejs.com/2013/06/the-race-for-speed-part-3-javascript-compiler-strategies/. I'm still not sure how much and for long code is stored in 'stub' form for a given piece of JavaScript. If it indeed remains compiled, then that would be in addition to the stored string. I can't picture .toString() as more than a simple string retrieval method.


#18

What I'm getting so far is that V8 doesn't interpret at all, it compiles everything. First it does a very fast compilation to get things running at all, and picks up information about the aplication from that and a second compiler or a more thorough compilation anyway uses that information and spends more time compiling to produce faster yet machine code, so as it warms up, it gets faster.

I don't see why an interpreter would ever drop what it has compiled, completely loading programs into memory is completely normal and chrome isn't exactly cheap on memory anyway.

Pretty sure your string is exclusively for the sake of debugging except possibly for very old interpreters but they should just parse it too. I also read something about actually looking at that string and analysing but that sounds really sketchy, the language evolves and there's no one standard interpreter. That string doesn't appear to have much in terms of promises for what it's supposed to look like. String conversion is for describing stuff, it's not what they are.


#19

A compromise for me (just so I can get my head around it) would be that nothing is compiled until it is called the first time. After that I can accept that it might remain in some form of token, or even native code. Will need to commit to more reading time on this topic to get closer to the bottom of it. It could be my resistence stems from how things were in the olden days.

Keep them cards and letters coming in!


#20

Firefox appears to interpret, compile and re-compile.
I think it's safe to say that no "big" language executes directly from source code.
Likewise, most OS's prevent anything from being completely compiled, programs have to use system calls for certain tasks that the OS wants to supervise. And the cpu is a physical interpreter, there's always that argument.

edit: better link. There were a bunch of entries to choose between, this one has a "In a nutshell, here’s how current release Firefox approaches JIT compilation"