It would be nice if there was a way to construct something similar around actor-based systems on the JVM.
It would be nice if there was a way to construct something similar around actor-based systems on the JVM.
Of course there are occasions where the name is unfortunate (typo, ambiguous name or incorrect term) but the docs could mention it and it would not be the end of the world.
It seems like most naming issues could be alleviated by allowing the developer to provide aliases, this way you can change the preferred parameter name while still keeping the old one around for backward compatibility.
They do in Swift's attempt at a keyword syntax.
You always have some concept of the API leak into the consumer. You either remember explicit names, or remember their positional pseudo-names 'first', 'second', 'third' etc. Unnamed arguments bring up more issues such as ordering consistency (see: PHP's many notorious cases), deprecation leaving 'holes' in argument lists, etc.
In Perl and many other languages we just provide a hash (aka dict) of key/value pairs. This lets the functions decide how to handle breaking changes which involves some annoying boilerplate but overall works fairly well. It's nicer with proper language support though.
The problem with named parameters as seen in Python is that then the name of the parameters become part of your APIs contract, making changes to your API harder. This has been remediated with patterns in Python 2 and explicit design in Python 3 by incorporating named only parameters so that you can't call them with both positional or named args.
So say I have a BankAccount class. In Python I would write a method to transfer to another account
def transfer(this, to, amount): ...
and invoke it as
account.transfer(other_account, 500)
In Smalltalk I would write
transferTo: account amount: n [ ... ]
and invoke it as
account transferTo: other_account amount: 500.
So it's not quite named arguments. It's that there isn't a distinction between name of function, argument name, and positional parameters. It just doesn't map to the function notation typical from mathematics.
Huh? How are APIs with mere positional parameters easier to change and more transparent to the callers when changed?
It is very deliberately inspired by Erlang and used widely in JVM applications.
foobar = send(actorA, GetDbVal(foo)) + send(actorB, GetDbVal(bar))
Instead you would need to construct some sort of mutable dictionary that keeps track of when it got both messages and when it does, have the actor finally add the stuff together. It’s not always so bad, but when you have actors that are interacting with a lot of other actors and querying many different resources, it becomes a problem. Akka tries to mitigate this problem with the state change function become(), which allows you to build a FSM to handle state transitions. While this helps a lot, it’s not a panacea.
I think I read somewhere that true multi-tasking is in the works for the JVM, so this hopefully won’t always be a problem. As it stands, it’s probably the biggest limitation of the platform atm.
bank move: 100 from: checkingAccount to: savingsAccount
Java: bank.move(100, checkingAccount, savingsAccount)bank.move(new Amount(100), new FromAccount(checkingAccount), new ToAccount(savingsAccount));
If you are really trying, you will be able to convey enough information so that your fellow programmer. will understand what you are trying to accomplish. Unfortunately, in practice, even Java Experts will convey to you that this style is wrong, classes and objects are " too expensive", primitive values are fine, and that this is too verbose.*
I learned about this style from Yegor Bugayenko's Book "Elegant Objects", go check it out. https://www.elegantobjects.org/
*) Yes, Java is verbose; not trying to defend that. I am very happy about keyword arguments in Python, for example. But, as soon as you have classes, ctors, objects, you can use them to add rich semantics into your code. Works with functional languages and other, better typesystems, too.
In Python, adding from=from_account, to=to_account to clarify a call is basically free; you don't have to change the callee and you don't have to change any other call sites.
very well said
bank.move(new Amount(100), AccountChannelFactory.create(AccountChannelFactory.CHECKING_CHANNEL, checkingAccount), AccountChannelFactory.create(AccountChannelFactory.SAVINGS_CHANNEL, savingsAccount));
bank.move( move: 100, from: checkingAccount, to: savingsAccount )
This option is also available for many of the other languages supported by the various JetBrains IDEs. bank balanceOf: (bank findAccount: #savings)
However, parens aren't necessary when a nested message takes no arguments, or uses a binary selector. eg: bank withdraw: 3 + 4 from: user checkingAccount
There are 3 messages here. 1. 3 + 4 (execute method + with argument 4)
2. user checkingAccount (getter with no arguments)
3. bank withdraw: <result of #1> from: <result of #2> bank.move(100, from=checkingAccount, to=savingsAccount)There have been some attempts to get Erlang running on the JVM but so far none that really made it worth adopting, and frankly I don't see how you could do it without losing everything that makes Erlang/OTP special.