Top language-features Questions

List of Tags
420
casademora

I saw this thread, but I didn't see a JavaScript specific example. Is there a simple string.Empty in JavaScript, or is it just checking for ""?

Answered By: bdukes ( 586)

If you just want to check whether there's any value, you can do

if (strValue) {
    //do something
}

If you need to check specifically for an empty string over null, I would think checking against "" is your best bet, using the === operator (so that you know that it is, in fact, a string you're comparing against).

212
divinci

Possible Duplicate:
How to enumerate an enum?

public enum Foos { A, B, C }

Is there a way to loop through the possible values of Foo?

Basically?

foreach(Foo in Foos)
Answered By: JaredPar ( 289)

Yes you can use the GetValues method

var values = Enum.GetValues(typeof(Foos));

Or the typed version

var values = Enum.GetValues(typeof(Foos)).Cast<Foos>();

I long ago added a helper function to my private library for just such an occasion

public static class EnumUtil {
  public static IEnumerable<T> GetValues<T>() {
    return Enum.GetValues(typeof(T)).Cast<T>();
  }
}

Usage:

var values = EnumUtil.GetValues<Foos>();
198
Michael Wolfenden

I'm asking with regards to c#, but I assume its the same in most other languages.

Does anyone have a good definition of expressions and statements and what the differences are?

Answered By: Joel Spolsky ( 270)

Expression: Something which evaluates to a value. Example: 1+2/x
Statement: A line of code which does something. Example: GOTO 100

In the earliest general-purpose programming languages, like FORTRAN, the distinction was crystal-clear. In FORTRAN, a statement was one unit of execution, a thing that you did. The only reason it wasn't called a "line" was because sometimes it spanned multiple lines. An expression on its own couldn't do anything... you had to assign it to a variable.

1 + 2 / X

is an error in FORTRAN, because it doesn't do anything. You had to do something with that expression:

X = 1 + 2 / X

FORTRAN didn't have a grammar as we know it today—that idea was invented, along with Backus-Naur Form (BNF), as part of the definition of Algol-60. At that point the semantic distinction ("have a value" versus "do something") was enshrined in syntax: one kind of phrase was an expression, and another was a statement, and the parser could tell them apart.

Designers of later languages blurred the distinction: they allowed syntactic expressions to do things, and they allowed syntactic statements that had values. The earliest popular language example that still survives is C. The designers of C realized that no harm was done if you were allowed to evaluate an expression and throw away the result. In C, every syntactic expression can be a made into a statement just by tacking a semicolon along the end:

1 + 2 / x;

is a totally legit statement even though absolutely nothing will happen. Similarly, in C, an expression can have side-effects—it can change something.

1 + 2 / callfunc(12);

because callfunc might just do something useful.

Once you allow any expression to be a statement, you might as well allow the assignment operator (=) inside expressions. That's why C lets you do things like

callfunc(x = 2);

This evaluates the expression x = 2 (assigning the value of 2 to x) and then passes that (the 2) to the function callfunc.

This blurring of expressions and statements occurs in all the C-derivatives (C, C++, C#, and Java), which still have some statements (like while) but which allow almost any expression to be used as a statement (in C# only assignment, call, increment, and decrement expressions may be used as statements; see Scott Wisniewski's answer).

Having two "syntactic categories" (which is the technical name for the sort of thing statements and expressions are) can lead to duplication of effort. For example, C has two forms of conditional, the statement form

if (E) S1; else S2;

and the expression form

E ? E1 : E2

And sometimes people want duplication that isn't there: in standard C, for example, only a statement can declare a new local variable—but this ability is useful enough that the GNU C compiler provides a GNU extension that enables an expression to declare a local variable as well.

Designers of other languages didn't like this kind of duplication, and they saw early on that if expressions can have side effects as well as values, then the syntactic distinction between statements and expressions is not all that useful—so they got rid of it. Haskell, Icon, Lisp, and ML are all languages that don't have syntactic statements—they only have expressions. Even the class structured looping and conditional forms are considered expressions, and they have values—but not very interesting ones.

Alan Storm's comments in response to my answer regarding the with statement got me thinking. I've seldom found a reason to use this particular language feature, and had never given much thought to how it might cause trouble. Now, I'm curious as to how I might make effective use of with, while avoiding its pitfalls...

So my question is, where have you found the with statement useful?

Answered By: Shog9 ( 317)

Another use occurred to me today, so i searched the web excitedly and found an existing mention of it: Defining Variables inside Block Scope.

Background

JavaScript, in spite of its superficial resemblance to C and C++, does not scope variables to the block they are defined in:

var name = "Joe";
if ( true )
{
   var name = "Jack";
}
// name now contains "Jack"

Declaring a closure in a loop is a common task where this can lead to errors:

for (var i=0; i<3; ++i)
{
   var num = i;
   setTimeout(function() { alert(num); }, 10);
}

Because the for loop does not introduce a new scope, the same num - with a value of 2 - will be shared by all three functions.

A new scope: let and with

With the introduction of the let statement in JavaScript 1.7, it becomes easy to introduce a new scope when necessary to avoid these problems:

for (var i=0; i<3; ++i)
{
   // variables introduced in this statement 
   // are scoped to the block following it.
   let (num = i) 
   {
      setTimeout(function() { alert(num); }, 10);
   }
}

But until other browsers implement it, this will remain limited to Mozilla-targeted code. However, we can easily simulate this behavior using with:

for (var i=0; i<3; ++i)
{
   // object members introduced in this statement 
   // are scoped to the block following it.
   with ({num: i})
   {
      setTimeout(function() { alert(num); }, 10);
   }
}

The loop now works as intended, creating three separate variables with values from 0 to 2. Note that variables declared within the block are not scoped to it - this is identical to the behavior of let, but unlike the behavior of blocks in C++ (in C, variables must be declared at the start of a block, so in a way it is similar).

I like the python list comprehension operator (or idiom, or whatever it is).

Can it be used to create dictionaries too? For example, by iterating over pairs of keys and values:

mydict = {(k,v) for (k,v) in blah blah blah}  # doesn't work :(
Answered By: fortran ( 291)

In Python 2.6 (or earlier), use the dict constructor:

d = dict((key, value) for (key, value) in sequence)

In Python 2.7+ or 3, you can just use the dict comprehension syntax directly:

d = {key: value for (key, value) in sequence}
function main()
{
   Hello();
}

function Hello()
{
  // How do you find out the caller function is 'main'?
}

Is there a way to find out the call stack at all?

Answered By: Greg Hewgill ( 198)
function Hello()
{
    alert("caller is " + arguments.callee.caller.toString());
}