views:

139

answers:

6

Hi! This is a reopened question.

I look for a language and supporting platform for it, where the language could have pass-by-reference or pass-by-name semantics by default. I know the history a little, that there were Algol, Fortran and there still is C++ which could make it possible; but, basically, what I look for is something more modern and where the mentioned value pass methodology is preferred and by default (implicitly assumed).

I ask this question, because, to my mind, some of the advantages of pass-by-ref/name seem kind of obvious. For example when it is used in a standalone agent, where copyiong of values is not necessary (to some extent) and performance wouldn't be downgraded much in that case. So, I could employ it in e.g. rich client app or some game-style or standalone service-kind application.

The main advantage to me is the clear separation between identity of a symbol, and its current value. I mean when there is no reduntant copying, you know that you're working with the exact symbol/path you have queried/received. And intristing boxing of values will not interfere with the actual logic of program.

I know that there is C# ref keyword, but it's something not so intristic, though acceptable. Equally, I realize that pass-by-reference semantics could be simulated in virtually any language (Java as an instant example) and so on.. not sure about pass by name :)

What would you recommend - create a something like DSL for such needs wherever it be appropriate; or use some languages that I already know? Maybe, there is something that I'm missing?

Thank you!

UPDATE: Currently, I think that Haskell would be appropriate. But I didn't investigate much, so I think I'll update this text later.

+4  A: 

Pass-by name is rare nowadays. However, you can simulate it in most functional programming languages using a lambda-nill:

// Pass by value
(dosomething (random))
// Pass by name hack
(dosomething (lambda () (random)))

Other then that: ML and O'CaML has a distinction between pass-by-value (default), pass-by-ref (using ref variables) and of course using lambdas. However, I'm not sure either of them qualifies as a "modern" language.

Little Bobby Tables
Very interesting, and I surely forgot about `ref` in OCaml, which is by it self more or less widely used. But hey) there is F#, which has the `ref` and I hope will be widely adopted. Thx.
Bubba88
+2  A: 

I'm not quite following your reasoning for why C#'s ref and out modifiers aren't "intrinsic." Seems to me that it provides almost exactly what you're looking for: A modern language and environment that supports pass-by-value and pass-by-reference. (As Little Bobby Tables pointed out, pass-by-name is very rare these days, you're better off with a lambda/closure.)

T.J. Crowder
+1  A: 

AFAIK, modern Fortran is pass-by-reference (preserving compatibility with ye olde FORTRAN).

Modern Fortran has all the niceties you expect of a modular language, so you can build just fine systems in it. Nobody does, because "Fortran is passe" and everybody wants to code in C# "because its cool.".

Ira Baxter
Never wrote a line in Fortran but would never said it is passe.
binary_runner
While the word Fortran scares me a little as it does to "everybody", I think it makes sense to take a look at it:)
Bubba88
@binary_runner: Fortran hardly ever comes as the language of choice for a new, complex system. People simply don't consider it all, in spite of being a modern langauge; they mostly think of it as "Fortran-the-dead-language". (OK, worse than passe!) Only scientists and engineers consider using it.
Ira Baxter
+4  A: 

Haskell has call-by-need as its default (and indeed only) evaluation strategy.

Now, you asked for two things: call-by-name and modern. Well, Haskell is a pure language and in a pure language call-by-name and call-by-need are semantically the same thing, or more precisely they always have the same result, the only difference being that call-by-need is usually faster and at worst only a constant factor slower than call-by-name. And Haskell surely is a modern language: it is merely 23 years old and in many of its features it is actually 10 years ahead of many languages that were created just recently.

The other thing you asked about is call-by-reference. Again, in a pure language, call-by-value and call-by-reference are the same thing, except that the latter is faster. (Which is why, even though most functional languages are usually described as being call-by-value, they actually implement call-by-reference.)

Now, call-by-name (and by extension call-by-need) are not the same thing as call-by-value (and by extension call-by-reference), because call-by-name may return a result in cases where call-by-value doesn't terminate.

However, in all cases where call-by-value or call-by-reference terminates, in a pure language, call-by-value, call-by-reference, call-by-name and call-by-need are the same thing. And in cases where they are not the same thing, call-by-name and call-by-need are in some sense "better", because they give you an answer in cases where call-by-value and call-by-reference would basically have run into an infinite loop.

Ergo, Haskell is your answer. Although probably not the one you were looking for :-)

Jörg W Mittag
Thx for the hint. Actually, among the current answers, yours seems to be the best. And I was a bit aware of Haskell and all its goodness.. but could you please give a link to more a descriptive outline of it's evaluation/passing strategy?
Bubba88
A: 

In Java, all objects are passed by reference.

JeremyP
Sorry but I think this should be called pass by pointer copy :)
Bubba88
That's an implementation detail.
JeremyP
No, thinking about it, it is not. There is a difference.
JeremyP
In Java, all arguments are passed by **value**. Including object references. The "reference" in "pass-by-reference" is a reference to the *variable* being passed, not the object, such that the called function can change the caller's variable's value.
T.J. Crowder
In Java, all objects are passed by value. In the case that the object in question is a real object, i.e. not a primitive, that value happens to be a pointer, but it is still a value. This special kind of call-by-value semantics was first named by Barbara Liskov as *call-by-sharing*. It is also sometimes called call-by-object-sharing or call-by-object, but unfortunately none of those three terms is in widespread use. It is most often simply called call-by-value, which is technically correct but grossly misleading. Some people call it call-by-reference which is plain wrong.
Jörg W Mittag
+4  A: 

Scala provides very flexible parameter passing semantics including real call-by-name:

def whileLoop(cond: => Boolean)(body: => Unit) {
  if (cond) {
    body
    whileLoop(cond)(body)
  }
}

And it really works

var i = 10
whileLoop (i > 0) {
  println(i)
  i -= 1
}

Technical details: Though all parameters are passed by value (and these are usually references) much like Java, the notation => Type will make Scala generate the required closures automatically in order to emulate call-by-name.

Note that there is lazy evaluation too.

lazy val future = evalFunc()


The interesting thing is that you have consistent strict call-by-value semantics but can punctually change these where you really need to - nearly without any syntactic overhead.

Dario
+1 for Scala, and the example is good.
Bubba88