The problem with this and the list comprehension equivalent
[io:format("Message: ~s~n", [Msg]) || Msg /= undefined]
is that it will confuse people who never encountered it before.
But if one or both of these forms were teached to beginners and everyone
was using them, then there'd be no problem in using them anymore.
I'd love if they became more popular.
Cheers,
--
Loïc Hoguin
https://ninenines.eu
# Viktor Söderqvist 2018-07-22:
>
> Msg /= undefined andalso io:format("Message: ~s~n", [Msg]),
>
> I this good or bad style?
It is horrible style. Pain to read, pain to modify, pain to reason about.
Simple clear question deserves a simple clear answer. :-)
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
How does it mess with types? The andalso and orelse operators should only care about the type of the first operand and it always is boolean.
Nicklaus Wirth, Turing Award 1984
.......
so whats your opinion about:
Msg /= undefined maybeornot io:format("Message: ~s~n", [Msg]),
or much more readable and clear with a well defined operator, because we
have a functional language:
Msg /= undefined F@*#! io:format("Message: ~s~n", [Msg]),
Markus Greim
No, that is *not* why andalso/2 was added to the language.The very spelling of the token, 'andalso', was copied froma language, Standard ML, which is strictly typed and doesnot allow <test> andalso <action>.
--
============================================================
Ivan A. Uemlianin PhD
Llaisdy
Ymchwil a Datblygu Technoleg Lleferydd
Speech Technology Research and Development
iv...@llaisdy.com
@llaisdy
llaisdy.wordpress.com
github.com/llaisdy
www.linkedin.com/in/ivanuemlianin
festina lente
============================================================
Yes, I know the RHS of 'andalso' is not typed in Erlang.So what? The point is that when 'andalso' and 'orelse'were copied into Erlang from Standard ML, they did notdrag the obsolete baggage of being ersatzes for WHEN andUNLESS in with them. They were added to providenon-strict AND and OR for Boolean expressions, and thatis all they were added for, just as 'and' and 'or' wereadded to provide strict AND and OR.They were not added to provide a cryptic way to obfuscateconditionals you could already easily write.
On 24 July 2018 at 03:48, 黃耀賢 (Yau-Hsien Huang) <g9414002.pccu.edu.tw@gmail.com> wrote:
Though the RHS of andalso is not typed in Erlang.
On Mon, Jul 23, 2018 at 10:35 PM, Richard O'Keefe <rao...@gmail.com> wrote:
No, that is *not* why andalso/2 was added to the language.The very spelling of the token, 'andalso', was copied froma language, Standard ML, which is strictly typed and doesnot allow <test> andalso <action>.
That code should die in a fire and the author should say repent with
the chanting of 100 Hail McCarthys.
-Craig
yep, now we are going in the right direction, that is self explaining!
Markus
> Ivan
>
>
> On 23/07/2018 15:16, Dmitry Kolesnikov wrote:
>> This is a clear case for Option data type…
>>
>> I would prefer to use explicit definition of a function that is able
>> to handle undefined values
>>
>> ```
>> print(undefined) ->
>> undefined;
>> print(Msg) ->
>> io:format("Message: ~s~n", [Msg]).
>> ```
>>
>> Alternatively, there is a parse transforms for composition of
>> maybe/option types
>> (https://github.com/fogfish/datum/blob/master/doc/category.md#option)
>>
>> Long time ago, I’ve used andalso syntax but it never stays longer at
>> code repository due to readability. It has been refactored to
>> function(s) with guards or pattern match.
>>
>> Best Regards,
>> Dmitry
>>
>>
>>> On 23 Jul 2018, at 16.32, Dmitry Belyaev <be.d...@gmail.com
>>> <mailto:be.d...@gmail.com>> wrote:
>>>
>>> How does it mess with types? The andalso and orelse operators should
>>> only care about the type of the first operand and it always is boolean.
>>>
>>> I personally don't like list comprehension as brackets create
>>> additional noise and might not be obvious to other developers.
>>>
>>> Also dialyzer may complain about unused value in either of ways, so
>>> the cleanest is probably case or if. The latter in Elixir doesn't
>>> require else branch which reduces noise a little bit.
>>>
>>> On 23 July 2018 21:05:37 GMT+10:00, Jesper Louis Andersen
>>> <jesper.lou...@gmail.com
>>> <mailto:jesper.lou...@gmail.com>> wrote:
>>>
>>> On Sun, Jul 22, 2018 at 9:09 PM Jachym Holecek
>>> <fr...@circlewave.net <mailto:fr...@circlewave.net>> wrote:
>>>
>>> # Viktor Söderqvist 2018-07-22:
>>> >
>>> > Msg /= undefined andalso io:format("Message: ~s~n", [Msg]),
>>> >
>>> > I this good or bad style?
>>>
>>> It is horrible style. Pain to read, pain to modify, pain to
>>> reason about.
>>>
>>> Simple clear question deserves a simple clear answer. :-)
>>>
>>>
>>> I don't like the style either, mostly because it messes with the
>>> types. andalso and orelse expects boolean expressions, but the
>>> style used breaks that format. However, something like
>>>
>>> [x || Msg /= undefined]
>>>
>>> doesn't.
>>>
>>>
>>> --
>>> Kind regards,
>>> Dmitry Belyaev
>>> _______________________________________________
>>> erlang-questions mailing list
>>> erlang-q...@erlang.org <mailto:erlang-q...@erlang.org>
"To me... well known"
Says it all.
Well, it’s a pattern I’ve seen in both lisp and javascript, so I agree that it’s not a totally wild idea. A pretty wide swath of programmers should be able to recognize what’s happening.
I feel like avoiding the pattern is more on the language than the programmer, too. You don’t see this pattern in languages without side-effects and you don’t get it when both sides of && must be booleans. OTOH if the language hands me a tool and I see a convenient use for it, why should I hold back?
I don’t understand the strong answers.
> I don’t understand the strong answers.
Then let me try to help :-)
> To me the semantics of orelse/and also are well known.
Are they? Or do you merely know of a different way to
(ab)use them?
> They are even known as ||/&& in the mainstream.
The "mainstream"? or C and bash and whatever? What about
Perl's: succeed() or die("fast")?
> They have their use as the common boolean shortcut
> operators.
Languages have their (ab)use by marketing persons and
spokespeople and lawyers; but does that make a better -
easier to learn, expressive, concise - language? a better
world for everyone (or most, actually)?
> These operators are very interesting semantics.
See? Now I have to guess whether this is merely a
(completely acceptable) mistake or something I do not (yet)
understand. Operators are no semantics, but ... It may as
well be that you confuse semantics with syntax, because you
say "easy-to-comment" below, so it might be the syntax
that appeals to you (and others, this all is not
meant to be personal :-).
> not exactly a pure language.
Off topic, this is about whether one codes for the compiler
or the programmer. No compiler has ever lamented about the
Obfuscated C Code Contest, full of things one _can_
write ... "Pure"? like 'completely and only functional'?
All programs will eventually push something to an output
device, which is inherently non-functional (or is it?)
> Being able to express side
> effects in such an easy-to-comment amount of code that’s
> just priceless.
Concise is fine, simply and only and first of all 'few
lines' is not price- but ruthless.
> Here’s a legit example:
> https://github.com/2600hz/kazoo/blob/master/applications/tasks/src/kz_tasks_scheduler.erl#L526
Is it legit? why? Why not:
if Pid =:= WorkerPid -> throw({'task', Task}) end,
? Not even now I am sure that this translation is correct,
and that after the much too long time that code forced me
to spend on understanding it. I am sure the compiler does
not complain ...
> So why the big words? What’s next, the process
> dictionary, using list comprehensions with 1-element
> lists generators?
In what better way would you express the process dict? Or
why not spawn a function and stuff all state into its
dictionary, have set/2 and get/1 to mutate and read the
attributes and call it OOerlang ... or WoeWoeErlang ...
If you want to translate/map or reduce/filter a list A to
produce a list B, it does not matter whether A happens to
have only one element or none (apart from []) or several or
many; that is what lists and list comprehension are meant
for. If one does not want to process a list, and does not
even want but create one -
[x || Msg /= undefined]
- then ... perhaps the author should die in a fire ;-)
Note: it does not matter what the compiler (writer) makes
of this.
> To me if you don’t like this kind of
> code it’s only because you have not needed / seen it
> much. So, read more code?
So if people have trouble walking on their hands they need
more practice?
Michael
P. S. All "you"s and "I"s are to be read as 'one'. This
really is not meant to be personal.
--
That, which was said, is not that, which was spoken,
but that, which was understood; and none of these
comes necessarily close to that, which was meant.
Why not:
if Pid =:= WorkerPid -> throw({'task', Task}) end,
?
Especially, I liked this point from Dmitry Kolesnikov:
> Long time ago, I’ve used andalso syntax but it never stays longer at
> code repository due to readability. It has been refactored to
> function(s) with guards or pattern match.
I think it is the process from prototyping to maintained code.
Refactoring involves gradually adding names to things by introducing
functions, adding specs and rewriting hacks into proper solutions. A
spec with a return type like false | ok | {error, Reason} would make me
reconsider the andalso trick. I guess this process gradually makes the
code change style from dynamically typed style (LISP, Perl) to
statically typed style (ML, Haskell). I find this interesting.
Viktor
On 2018-07-22 14:25, Viktor Söderqvist wrote:
> Hey everyone,
>
> I've seen these short-circuit operators with a non-boolean second
> operand, usually where the second operand is doing some side-effect and
> the return value is not important. It seems to be a trend. Example:
>
> Msg /= undefined andalso io:format("Message: ~s~n", [Msg]),
>
> I this good or bad style?
-Craig
On 2018年7月25日水曜日 15時00分03秒 JST Richard O'Keefe wrote:
> Pierre Fenoli does not "understand the strong answers".
> I imagine that other people have had the experience of having to maintain
> someone else's code, and after a long struggle to disentangle unduly
> "clever"
> code found themselves shouting "Why did this offspring of an incestuous
> union between two male naked mole-rats not remove xer hands from xer
> genitals long enough to write down what xie actually meant and NOT WASTE
> MY RAPIDLY DWINDLING TIME?"
>
> I am still nowhere near as good a programmer as I would like to be.
> I need to make my own code clearer.
> "What is hateful to you, do not do to others."
> If anyone catches me abusing short-circuit operations, my apologies
> in advance.
>
> The andalso and orelse operators are defined in section 8.14
> http://erlang.org/doc/reference_manual/expressions.html#short-circuit-expressions
> of the Erlang reference manual. It is clear from that that
> these operators originally required their right operand to yield
> true or false, and were only changed in order to allow code like
>
>
> ismember(X, [Y|Ys]) -> X == Y orelse ismember(X, Ys);
> ismember(_, [] ) -> false.
>
> to be tail recursive.
>
> It would be really nice if the Dialyzer would warn about misuses of
> these operators. What about the 'legit example' we were offered?
> It is a blemish in an otherwise pleasant file in an impressive and
> useful project. The only occurrence of 'andalso' in that 628 line
> file is a good example of when NOT to use 'andalso'.
>
> task_by_pid(Pid, #state{tasks = Tasks}) ->
> F = fun (_, #{worker_pid := WorkerPid}=Task, Acc) ->
> Pid =:= WorkerPid
> andalso throw({'task', Task}),
> Acc
> end,
> try maps:fold(F, 'undefined', Tasks)
> catch 'throw':{'task', Task} -> Task
> end.
>
> which is 9 lines. It garden-paths the reader into a
> sort of double negation. The goal of F is *not* to return Acc,
> but to find a Task, and the throw is *not* there to report
> failure, but success.
>
> This can be written, not only without 'andalso',
> but also without 'throw' and 'catch', as
>
> task_by_id(Pid, #state{tasks = Tasks}) ->
> task_with_matching_worker_pid(Pid, Tasks).
>
> task_with_matching_worker_pid(Pid, [Task = #{worker_pid := Pid}|_]) ->
> Task;
> task_with_matching_worker_pid(Pid, [_|Tasks]) ->
> task_with_matching_worker_pid(Pid, Tasks);
> task_with_matching_worker_pid(_, []) ->
> undefined.
>
> which is also 9 lines. To me this is a fairly obvious linear
> search for a matching list element, which leaves me free to
> think about things like whether a map from worker Pids to Tasks
> might not be a better data structure, and also lets me muse,
> "hmm, isn't there already a library function to look for the
> first matching list element? Oh yeah."
>
> task_by_pid(Pid, #state{tasks = Tasks}) ->
> case lists:search(fun (#{worker_pid := Id}) -> Id =:= Pid end, Tasks)
> of {value, Task} -> Task
> ; false -> undefined
> end.
>
> which is now 5 lines, and is how I'd have written it in the first place.
>
> I honestly wasn't expecting this. Given that this was Kazoo, I
> was expecting to have to mumble and shuffle and say "well, maybe
> OCCASIONALLY you can get away with it in otherwise really good
> code", but the abuse of 'andalso' DID turn out to be a 'code smell'
> pointing to contorted code that needed rewriting.
>
> If, as would not be surprising, I have misunderstood thpe original
> code, that just proves my point that it was contorted.
This painful guideline saves me much torment every time I find the fortitude to apply it.
-Craig
I'm not sure. A lot of the messages from him I wind up getting I receive
because I'm on the recipient list separately from the ML (maybe from "reply
to all"?). erlang-questions is usually just CC'd -- which should work just
fine. I can't imagine anyone would filter ROK's messages *out* of the list.
Much to the contrary, if I had the time I would put together a compilation
of his best posts/threads!
So, Richard, if you happen to read this... any idea why your mail isn't
hitting the list lately? Maybe one account or another is unsubscribed?
-Craig
A common cause of problems for Mailing lists is the presence or absence
of an SPF record for custom domains. I can't see ROK's e-mail address
from your reposts, but you can do a quick check by doing a DNS lookup.
Here's mine for example:
→ dig ferd.ca ANY
...
;; ANSWER SECTION:
ferd.ca. 3599 IN A 208.94.116.79
ferd.ca. 3599 IN MX 5 ALT2.ASPMX.L.GOOGLE.COM.
ferd.ca. 3599 IN MX 10 ASPMX5.GOOGLEMAIL.COM.
...
ferd.ca. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"
ferd.ca. 3599 IN SOA ns.phx1.nearlyfreespeech.net. hostmaster.nearlyfreespeech.net. 1406273317 600 180 86400 180
The MX records indicate that I'm redirecting everything on gmail, but
the critical one not to be seen as spam or a spoofed e-mail is the TXT
record with the SPF entry in it.
Background info is at https://support.dnsimple.com/articles/spf-record/
or https://en.wikipedia.org/wiki/Sender_Policy_Framework
-- your mail provider should possibly be able to give a line about it so
people can configure their stuff themselves. Google's page is at
https://support.google.com/a/answer/33786?hl=en if you're using gmail.
There's a good chance that something like that could be to blame for
missing/non-forwarded e-mails.
Regards,
Fred.
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
Surely you're not suggesting that ROK would ever *forget* anything?:-)
But mailing list configuration is likely - AFAIR, this list like most
others block messages from non-subscribers to cut down on spam. And the
last message directly from Richard that I still have in my inbox happens
to be this one:
http://erlang.org/pipermail/erlang-questions/2017-November/094170.html
Raimo did dutifully reply to that message, but one possibility is that
Richard didn't get around to re-subscribing, and get the list messages
forwarded from his old address, while his own messages that use the new
address are blocked. Raimo, maybe you can have a look? I know that it's
outside what can be expected from standard mailing list maintenance, but
this concerns a very special subscriber...
--Per
> On 28 July 2018 12:29:57 GMT+10:00, Fred Hebert <mono...@ferd.ca> wrote:
>
> On 07/28, zx...@zxq9.com wrote:
>
>
> So, Richard, if you happen to read this... any idea why your mail isn't
> hitting the list lately? Maybe one account or another is unsubscribed?
>
>
>
> A common cause of problems for Mailing lists is the presence or absence
> of an SPF record for custom domains. I can't see ROK's e-mail address
> from your reposts, but you can do a quick check by doing a DNS lookup.
> Here's mine for example:
>
> ’ dig ferd.ca ANY
> ...
> ;; ANSWER SECTION:
> ferd.ca. 3599 IN A 208.94.116.79
> ferd.ca. 3599 IN MX 5 ALT2.ASPMX.L.GOOGLE.COM.
> ferd.ca. 3599 IN MX 10 ASPMX5.GOOGLEMAIL.COM.
> ...
> ferd.ca. 3599 IN TXT "v=spf1 include:_spf.google.com ~all"
> ferd.ca. 3599 IN SOA ns.phx1.nearlyfreespeech.net. hostmaster.nearlyfreespeech.net. 1406273317 600 180 86400 180
>
> The MX records indicate that I'm redirecting everything on gmail, but
> the critical one not to be seen as spam or a spoofed e-mail is the TXT
> record with the SPF entry in it.
>
> Background info is athttps://support.dnsimple.com/articles/spf-record/
> orhttps://en.wikipedia.org/wiki/Sender_Policy_Framework
> -- your mail provider should possibly be able to give a line about it so
> people can configure their stuff themselves. Google's page is at
> https://support.google.com/a/answer/33786?hl=en if you're using gmail.
>
> There's a good chance that something like that could be to blame for
> missing/non-forwarded e-mails.
>
> Regards,
> Fred.
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> erlang-questions mailing list
> erlang-q...@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
> --
> Kind regards,
> Dmitry Belyaev
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-q...@erlang.org
> http://erlang.org/mailman/listinfo/erlang-questions
>
_______________________________________________
In Erlang:
f() ->
other:check_db_ok() andalso other:do_db_transaction().
After compilation with +to_core:
f'/0 =
fun () ->
( case call 'other':'check_db_ok'
() of
( <( 'true'
-| ['compiler_generated'] )> when 'true' ->
call 'other':'do_db_transaction'
()
-| ['compiler_generated'] )
( <( 'false'
-| ['compiler_generated'] )> when 'true' ->
'false'
-| ['compiler_generated'] )
( <_@c0> when 'true' ->
( call ( 'erlang'
-| ['compiler_generated'] ):( 'error'
-| ['compiler_generated'] )
(( {( 'badarg'
-| ['compiler_generated'] ),_@c0}
-| ['compiler_generated'] ))
-| ['compiler_generated'] )
-| ['compiler_generated'] )
end
-| ['compiler_generated'] )
Which, as we've all been discussing, is the same as a case expression, and furthermore is de-sugared as such.
24.07.2018, 08:20, "Pierre Fenoll" <pierre...@gmail.com>:
> ,