任何具有“奇怪”特征的编程语言函数调用?
我想知道,是否有任何编程语言可以进行这样的函数调用:
function_name(parameter1)function_name_continued(parameter2);
或者
function_name(param1)function_continued(param2)...function_continued(paramN);
例如,您可以进行此函数调用:
int dist = distanceFrom(cityA)to(cityB);
如果您定义了这样的 distanceFromto
函数:
int distanceFrom(city A)to(city B)
{
// find distance between city A and city B
// ...
return distance;
}
据我所知,在C、Java和SML编程语言中,这是无法做到的。
您是否知道任何可以让您定义和调用的编程语言 这样的功能?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
它看起来非常像 Objective-C
It looks an awful lot like Objective-C
听起来很像 Smalltalk 的语法(这可以解释 Objective-C 的语法 - 请参阅 kubi 的答案)。
示例:
其中 #distanceFrom:to: 是某个名为 metric 的对象上的方法。
所以你有“函数调用”(它们实际上是消息发送),比如
编辑:我说过“真的,#distanceFrom:to: 应该在 City 类上调用 #distanceTo:,但无论如何。” Justice 指出,这将城市与指标联系在一起,这是不好的。您可能想要改变度量标准的原因有很多——飞机可能使用测地线,而汽车可能使用基于道路网络的最短路径。)
Sounds a lot like Smalltalk's syntax, (which would explain Objective-C's syntax - see kubi's answer).
Example:
where #distanceFrom:to: is a method on some object called metric.
So you have "function calls" (they're really message sends) like
EDIT: I'd said "Really, #distanceFrom:to: should be called #distanceTo: on a City class, but anyway." Justice points out that this couples a City to a Metric, which is Bad. There are good reasons why you might want to vary the metric - aeroplanes might use a geodesic while cars might use a shortest path based on the road network.)
出于好奇,Agda2 有一个类似的、非常宽松的语法。以下是有效代码:
如果
进行评估,则结果为
For the curious, Agda2 has a similar, very permissive syntax. The following is valid code:
If
is evaluated, the result is
看起来很像流畅的界面或方法链接给我。
Looks a lot like a fluent interface or method chaining to me.
在 Python 中,您可以显式传递调用函数的参数名称,这使您可以以不同的顺序传递它们或跳过可选参数:
这看起来很像 Objective C 语法所做的事情,标记每个参数到一个带有其名称的函数。
In Python, you can explicitly pass the name of the arguments you're calling the function with, which lets you pass them in a different order or skip optional arguments:
This looks a lot like what the Objective C syntax is doing, tagging each argument to a function with its name.
C# 4.0 的 命名和可选参数 功能允许您实现非常相似的目标:
C# 4.0's Named and Optional Arguments feature allows you to achieve something pretty similar:
(请参阅我最喜欢的个人努力 - 本答案末尾的最终 C++ 方法)
语言一
Objective-C 但调用语法是 [object message] 所以看起来像:
如果您定义了 < code>distanceFromto 像这样的函数,在城市对象中:
语言二
我也怀疑你可以在 IO Language 但我只是看看它。您可能还想了解它与其他语言的比较 七周掌握七种语言,其中有关于 IO 的免费摘录 。
第三种语言
根据 C++ 的设计和演变 看起来像这样:
如果您定义了这样的
distanceFrom
函数,带有一个小辅助对象。请注意,内联函数使此类内容编译为非常高效的代码。呃,我之前很着急,意识到我可以重构为仅使用临时对象来提供相同的语法:
我最喜欢的
这里有一个更具启发性的 C++ 版本,它允许您编写
甚至
基于#define 和类的精彩 C++ 风格组合:
注意这可能看起来像是一个无用的练习,但在某些情况下它可以是对于为人们提供 C++ 中的特定于领域的语言非常有用,他们可以将其与库一起编译。我们对 CSIRO 的地理建模科学家使用了类似的 Python 方法。
(see my very favourite personal effort - the final C++ approach at the end of this answer)
Language One
Objective-C but the calling syntax is [object message] so would look like:
if you have defined
distanceFromto
function like this, within a cities object:Language Two
I also suspect you could achieve something very close to this in the IO Language but I'm only just looking at it. You may also want to read about it in comparison to other languages in Seven Languages in Seven Weeks which has a free excerpt about IO.
Language Three
There's an idiom ("chaining") in C++ where you return temporary objects or the current object that is used to replace keyword arguments, according to The Design and Evolution of C++ and looks like this:
if you have defined
distanceFrom
function like this, with a little helper object. Note that inline functions make this kind of thing compile to very efficient code.Duhh, I was in a hurry earlier, realised I can refactor to just use a temporary object to give the same syntax:
MY FAVOURITE
and here's an even more inspired C++ version that allows you to write
or even
based on a wonderfully C++ ish combination of #define and classes:
NOTE this may look like a useless exercise but in some contexts it can be very useful to give people a domain-specific language in C++ which they compile alongside libraries. We used a similar approach with Python for geo-modeling scientists at the CSIRO.
您可以在 C 中执行此操作,尽管不安全:
使用 compound文字和指定初始化器 。
You can do this in C, albeit unsafely:
uses compound literals and designated initializers.
RemObjects 的 Elements Compiler 中的 4 种联合语言中的 3 种在 OP 所请求的语法中具有此功能(以支持 Objective-C 运行时,但可用于所有操作系统)。
在 Hydrogene(扩展的 C#)中
碘
(扩展的 Java)
https://docs.elementscompiler.com/Iodine/LanguageExtensions/MultiPartMethodNames
Oxygene 中的 (扩展的 ObjectPascal),向下滚动到多部分方法名称部分
https://docs.elementscompiler.com/Oxygene/Members/Methods
3 of the 4 confederated languages from RemObjects in their Elements Compiler have this capability in precisely the OP's requested syntax (to support Objective-C runtime, but made available to all operating systems).
in Hydrogene (an extended C#)
https://docs.elementscompiler.com/Hydrogene/LanguageExtensions/MultiPartMethodNames
in Iodine (an extended Java)
https://docs.elementscompiler.com/Iodine/LanguageExtensions/MultiPartMethodNames
in Oxygene (an extended ObjectPascal), scroll down to Multi-Part Method Names section
https://docs.elementscompiler.com/Oxygene/Members/Methods
这看起来类似于函数重载 (C++/C#)/默认参数 (VB)。
默认参数允许定义函数的人为后面的参数设置默认值:
例如c#重载:
This looks similar to function overloading (C++/C#)/default parameters (VB).
Default Parameters allow the person defining the function to set defaults for the latter parameters:
e.g. c# overloading:
您可以为此使用成员函数。
这是 C++、C(稍作调整)、C#、Java 中的有效代码。使用方法链,您可以执行以下操作:
You can use a member function for this.
That's valid code in C++, C(with a little tweaking), C#, Java. Using method chains, you can do:
在 SML 中,您可以简单地将“to”设置为某个值(例如单位),并将“distanceFrom”设置为带有三个参数的柯里化函数。例如:
您还可以利用 SML 不强制执行 datataype 构造函数命名约定的事实(这让很多人感到烦恼),因此如果您想确保类型系统强制执行您的自定义语法:
In SML you could simply make "to" some value (unit, for example), and "distanceFrom" a curried function that takes three parameters. For example:
You could also take advantage of the fact that SML doesn't enforce naming conventions on datataype constructors (much to many peoples' annoyance), so if you want to make sure that the type system enforces your custom syntax:
您可以在Scheme 或LISP 中使用宏来完成此操作。
形式类似于:
大写的符号表示语法。
您甚至可以执行“命名参数”之类的操作:
You could do this in Scheme or LISP using macros.
The form will be something like:
The symbols in uppercase denotes syntax.
You could even do something like 'named parameters':
Tcl 允许你做这样的事情:
我不确定这是否正是你所想的。
Tcl allows you to do something like this:
I'm not sure if that's quite what you are thinking of though.
您可以在Java中执行此操作,使用构建器模式 出现在 Joshua Bosch 的《Effective Java》一书中(这是我第二次将此链接放在 SO 中,我仍然没有使用那种模式,但看起来很棒)
You can do it in Java, Use Builder pattern that appears in the book Effective Java by Joshua Bosch (this is second time I put this link in SO, I still didn't use that patern, but looks great)
那么,在 Felix 中,您可以分两步实现:首先,编写一个普通函数。然后,您可以扩展语法并将一些新的非终结符映射到函数。
与您可能想要的相比,这有点重量级(欢迎帮助使其变得更容易!!)我认为这可以满足您的需求,甚至更多!
我将举一个真实的例子,因为整个 Felix 语言实际上都是通过这种技术定义的(下面的 x 是表达式的非终结符,x[p] 中的 p 是优先级代码):
这里还有更多信息:
Felix 语法是普通用户代码。在示例中,语法操作是用Scheme 编写的。语法是GLR。它允许“上下文敏感关键字”,即标识符仅在某些上下文中是关键字,这使得发明新结构变得容易,而不必担心破坏现有代码。
也许您想查看Felix Grammar Online。
Well, in Felix you can implement this in two steps: first, you write an ordinary function. Then, you can extend the grammar and map some of the new non-terminals to the function.
This is a bit heavyweight compared to what you might want (welcome to help make it easier!!) I think this does what you want and a whole lot more!
I will give a real example because the whole of the Felix language is actually defined by this technique (below x is the non-terminal for expressions, the p in x[p] is a precedence code):
Here's a bit more:
The Felix grammar is ordinary user code. In the examples the grammar actions are written in Scheme. The grammar is GLR. It allows "context sensitive keywords", that is, identifiers that are keywords in certain contexts only, which makes it easy to invent new constructs without worrying about breaking existing code.
Perhaps you would like to examine Felix Grammar Online.