Bubba88
Bubba88

Reputation: 1920

Is there a language with native pass-by-reference/pass-by-name semantics, which could be used in modern production applications?

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.

Upvotes: 2

Views: 1599

Answers (6)

Dario
Dario

Reputation: 49218

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.

Upvotes: 5

JeremyP
JeremyP

Reputation: 86671

In Java, all objects are passed by reference.

Upvotes: -1

Jörg W Mittag
Jörg W Mittag

Reputation: 369574

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 :-)

Upvotes: 4

Ira Baxter
Ira Baxter

Reputation: 95400

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.".

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1075219

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.)

Upvotes: 2

Little Bobby Tables
Little Bobby Tables

Reputation: 5351

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.

Upvotes: 4

Related Questions