是否有一种编程语言允许在调用站点声明变量?
更新 2:示例被删除,因为它们具有误导性。下面的内容更相关。
我的问题:
是否有一种具有这种结构的编程语言?
更新: 现在我想起来,Prolog 也有类似的东西。 我什至允许在定义行定义操作。 (忘记回溯和关系 - 考虑语法)
我问这个问题是因为我相信,语言中具有对称性是一件好事。 “输入”参数和“输出”参数之间的对称性。
如果返回这样的值很容易,我们可以在设计语言中放弃显式返回。
重新配对...我认为这是一个黑客行为。我们不需要数据结构来将多个参数传递给函数。
更新2:
给出一个我正在寻找的语法示例:
f (s, d&) = // & indicates 'out' variable
d = s+s.
main =
f("say twice", &twice) // & indicates 'out' variable declaration
print(twice)
main2 =
print (f("say twice", _))
或者以函数+序言风格
f $s (s+s). // use $ to mark that s will get it's value in other part of the code
main =
f "say twice" $twice // on call site the second parameter will get it's value from
print twice
main2 =
print (f "Say twice" $_) // anonymous variable
在提议的语言中,没有表达式,因为所有返回都是通过参数。在深层次函数调用很自然的情况下,这会很麻烦。 Lisp'ish 示例:
(let x (* (+ 1 2) (+ 3 4))) // equivalent to C x = ((1 + 2) * (3 + 4))
需要在所有临时变量的语言名称中:
+ 1 2 res1
+ 3 4 res2
* res1 res2 x
所以我建议将整个函数调用转换为该变量的值的匿名变量:
* (+ 1 2 _) (+ 3 4 _)
这不是很自然,因为我们有所有的文化包袱,但我想要抛弃我们目前对语法的所有先入之见。
Update 2: examples removed, because they were misleading. The ones below are more relevant.
My question:
Is there a programming language with such a construct?
Update:
Now when I think about it, Prolog has something similar.
I even allows defining operations at definition line.
(forget about backtracking and relations - think about syntax)
I asked this question because I believe, it's a nice thing to have symmetry in a language.
Symmetry between "in" parameters and "out" parameters.
If returning values like that would be easy, we could drop explicit returning in designed language.
retruning pairs ... I think this is a hack. we do not need a data structure to pass multiple parameters to a function.
Update 2:
To give an example of syntax I'm looking for:
f (s, d&) = // & indicates 'out' variable
d = s+s.
main =
f("say twice", &twice) // & indicates 'out' variable declaration
print(twice)
main2 =
print (f("say twice", _))
Or in functional + prolog style
f $s (s+s). // use $ to mark that s will get it's value in other part of the code
main =
f "say twice" $twice // on call site the second parameter will get it's value from
print twice
main2 =
print (f "Say twice" $_) // anonymous variable
In a proposed language, there are no expressions, because all returns are through parameters. This would be cumbersome in situations where deep hierarchical function calls are natural. Lisp'ish example:
(let x (* (+ 1 2) (+ 3 4))) // equivalent to C x = ((1 + 2) * (3 + 4))
would need in the language names for all temporary variables:
+ 1 2 res1
+ 3 4 res2
* res1 res2 x
So I propose anonymous variables that turn a whole function call into value of this variable:
* (+ 1 2 _) (+ 3 4 _)
This is not very natural, because all the cultural baggage we have, but I want to throw away all preconceptions about syntax we currently have.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
调用 f() 后会看到 $twice,它具有预期值。如果删除 & 符号,则会出现错误。所以看起来 PHP 会在调用时声明变量。不过,我不相信这会给你带来多大好处,尤其是在 PHP 方面。
$twice is seen after the call to f(), and it has the expected value. If you remove the ampersand, there are errors. So it looks like PHP will declare the variable at the point of calling. I'm not convinced that buys you much, though, especially in PHP.
“有没有一种编程语言具有这样的结构?”
你的问题其实有点不清楚。
从某种意义上说,任何支持对函数参数[关联的变量状态]进行赋值的语言都支持“这样的构造”。
C 支持它,因为“void f (type *address)”允许修改地址指向的任何内容。 Java 支持它,因为“void f (Object x)”允许对 x 的某些方法进行任何(状态修改)调用。 COBOL 支持它,因为“PROCEDURE DIVISION USING X”可以涉及保存指针/内存地址的 X,最终允许更改该地址所指向的事物的状态。
从这个角度来看,我想说几乎人类已知的所有语言都支持“这样的构造”,也许除了像Tutorial D这样声称“完全无指针”的语言。
"Is there a programming language with such a construct?"
Your question is in fact a little unclear.
In a sense, any language that supports assignment to [the variable state associated with] a function argument, supports "such a construct".
C supports it because "void f (type *address)" allows modification of anything address points to. Java supports it because "void f (Object x)" allows any (state-modifying) invocation of some method of x. COBOL supports it because "PROCEDURE DIVISION USING X" can involve an X that holds a pointer/memory address, ultimately allowing to go change the state of the thing pointed to by that address.
From that perspective, I'd say almost every language known to mankind supports "such a construct", with the exception perhaps of languages such as Tutorial D, which claim to be "absolutely pointer-free".
我很难理解你想要什么。您想将返回类型放在调用签名上吗?我确信有人可以将其组合在一起,但这真的有用吗?
我感觉这将在内部以这种方式实现:
I'm having a hard time understanding what you want. You want to put the return type on call signature? I'm sure someone could hack that together but is it really useful?
I get the feeling this would be implemented internally this way:
对于您的第一个代码片段,我不知道有任何此类语言,坦率地说,我很高兴确实如此。像这样在表达式中间声明一个变量,然后在所述表达式之外使用它,对我来说看起来非常错误。如果有的话,我希望此类变量的范围仅限于函数调用,但当然,它首先是毫无意义的。
对于第二个 - 多个返回值 - 几乎任何具有一流元组支持的语言都有类似的东西。例如Python:
Lua没有一流的元组(即你不能将元组值绑定到单个变量 - 你总是必须扩展它,可能会丢弃它的一部分),但它确实有多个返回值,本质上是相同的语法:
F# 具有一流的元组,因此前面所说的有关 Python 的所有内容也适用于它。但它也可以模拟在 C# 或 VB 中使用
out
或ref
参数声明的方法的元组返回,这可能是最接近您所描述的 - 尽管它仍然是隐式(即您根本不指定外参数,即使是_
)。例子:For your first code snippet, I'm not aware of any such languages, and frankly I'm glad it is the case. Declaring a variable in the middle of expression like that, and then using it outside said expression, looks very wrong to me. If anything, I'd expect the scope of such variable to be restricted to the function call, but then of course it's quite pointless in the first place.
For the second one - multiple return values - pretty much any language with first-class tuple support has something close to that. E.g. Python:
Lua doesn't have first-class tuples (i.e. you can't bind a tuple value to a single variable - you always have to expand it, possibly discarding part of it), but it does have multiple return values, with essentially the same syntax:
F# has first-class tuples, and so everything said earlier about Python applies to it as well. But it can also simulate tuple returns for methods that were declared in C# or VB with
out
orref
arguments, which is probably the closest to what you describe - though it is still implicit (i.e. you don't specify the out-argument at all, even as_
). Example:以下是在 Perl 中执行此操作的方法:
[编辑] 另外,由于您似乎对最小语法感兴趣:
是完全有效的 perl。下面是正常引用逗号用法的示例:
另外,对于返回值,除非提前以“return”退出,否则所有 perl 子例程都会自动返回它们执行的最后一行,无论是单个值还是列表。最后,看一下 perl6 的 feed 操作符,您可能会觉得有趣。
[/edit]
我不确定你到底想用第二个例子实现什么,但是隐式变量的概念存在于一些语言中,在 Perl 中,它是 $_。
一个例子是 Perl 的一些内置函数,当它们没有参数时,它们会查看 $_ 。
如果不使用 $_,上面的代码将是:
$_ 在 perl 中的许多情况下使用,以避免重复将临时变量传递给函数
Here is how you would do it in Perl:
[edit] Also, since you seem interested in minimal syntax:
is perfectly valid perl. Here's an example of normal quoting comma usage:
Also, on return values, unless exited with a "return" early, all perl subroutines automatically return the last line they execute, be it a single value, or a list. Lastly, take a look at perl6's feed operators, which you might find interesting.
[/edit]
I am not sure exactly what you are trying to achieve with the second example, but the concept of implicit variables exists in a few languages, in Perl, it is $_.
an example would be some of perl's builtins which look at $_ when they dont have an argument.
without using $_, the above code would be:
$_ is used in many cases in perl to avoid repeatedly passing temporary variables to functions
不是编程语言,而是各种进程演算具有用于在依赖于它们的进程表达式范围内的接收者调用站点处绑定名称的语法。虽然 Pict 有这样的语法,但它没有在您所询问的派生函数语法中实际上没有意义。
Not programming languages, but various process calculi have syntax for binding names at the receiver call sites in the scope of process expressions dependent on them. While Pict has such syntax, it doesn't actually make sense in the derived functional syntax that you're asking about.
您可以查看Oz。在 Oz 中,您只有过程,并且将值分配给变量而不是返回它们。
它看起来像这样:
有一些函数(返回值),但这只是语法糖。
另外,计算机编程的概念、技术和模型是一本很棒的 SICP-就像使用 Oz 和莫扎特编程系统教授编程的书一样。
You might have a look at Oz. In Oz you only have procedures and you assign values to variables instead of returning them.
It looks like this:
There are functions (that return values) but this is only syntactic sugar.
Also, Concepts, Techniques, and Models of Computer Programming is a great SICP-like book that teaches programming by using Oz and the Mozart Programming System.
我不这么认为。大多数执行类似操作的语言都使用元组,以便可以有多个返回值。想想看,C 风格的引用和输出参数主要是为了不返回元组而进行的修改......
I don't think so. Most languages that do something like that use Tuples so that there can be multiple return values. Come to think of it, the C-style reference and output parameters are mostly hacks around not being about to return Tuples...
有点令人困惑,但 C++ 非常喜欢声明变量并将它们作为同一语句中的输出参数传递:
但不要在混淆竞赛之外这样做。
您可能还想查看按名称传递语义在 Algol 中,你的完整描述闻起来有点相似。
Somewhat confusing, but C++ is quite happy with declaring variables and passing them as out parameters in the same statement:
But don't do that outside of obfuscation contests.
You might also want to look at pass by name semantics in Algol, which your fuller description smells vaguely similar to.