[erlang-questions] Dynamically access record fields
Loïc Hoguin
essen@REDACTED
Tue Feb 12 03:04:31 CET 2013
On 02/12/2013 02:06 AM, ok@REDACTED wrote:
> "Loïc Hoguin" <essen@REDACTED> wrote
>
>> - Micro optimization. Most applications wouldn't care for it either
> Applications cannot care or not care for anything.
> If people are willing to pay the price, fine;
> my problem was that I saw no evidence that any proponent
> realised that there _was_ a price "I just don't see the harm".
Pedantic point. If execution speed isn't an application requirement,
then there's no need to even concern yourself about it, because
everything else is more important.
You'll also most likely improve the execution speed of your system by
improving inter-process communication and application architecture
rather than having to execute one less instruction here and there.
>> - That's a developer's choice
> Making code less readable may be a developer's _choice_,
> but if anyone else might be required to read the code,
> it isn't a developer's _right_.
You seem to think code readability isn't subjective.
>> - BS, you have the same issue with Var = #rec.field, no difference there
> Reducing the effectiveness of type checking?
> Yes, we do have the same issue with Var = #rec.field,
> BUT I don't say that using that is a good idea either.
Sometimes there's no good solution and you still have to get things
done. However, as far as "bad" solutions go, #rec.field is worse than
'field', because you'll get a meaningless integer when you output the
value when debugging, instead of what could have been an atom.
>> - See previous point
> Inadvertently providing wider access? No, this one is
> quite different from #rec.field. You can only use
> #rec.field within the compile-time scope of a -record
> declaration for 'rec'. If #rec.Field were allowed,
> Field could be created at a point where the record
> declaration was _not_ visible. #rec.field has to be
> inside the module; use of it is not inadvertent; and
> you can _find_ it trivially with a text editor, so
> you can very easily check which fields might be accessed
> that way. As far as I can see, that's not true of
> #rec.Field, where Field comes from some unknown arbitrary
> module.
Well, #rec.Field is not possible to begin with, and wouldn't make sense
for records. But it would definitely be good for another data type, as
I'll explain.
> The key point is that we just plain DON'T NEED #rec.Field;
> anything we could do with it can be done without it more
> clearly using existing mechanisms, with better control over
> access and all sorts of other programmer-liked goodness.
There's nothing clear in having to write:
g(bindings, #http_req{bindings=Ret}) -> Ret;
g(body_state, #http_req{body_state=Ret}) -> Ret;
g(buffer, #http_req{buffer=Ret}) -> Ret;
g(connection, #http_req{connection=Ret}) -> Ret;
g(cookies, #http_req{cookies=Ret}) -> Ret;
g(fragment, #http_req{fragment=Ret}) -> Ret;
g(headers, #http_req{headers=Ret}) -> Ret;
g(host, #http_req{host=Ret}) -> Ret;
g(host_info, #http_req{host_info=Ret}) -> Ret;
g(meta, #http_req{meta=Ret}) -> Ret;
g(method, #http_req{method=Ret}) -> Ret;
g(multipart, #http_req{multipart=Ret}) -> Ret;
g(onresponse, #http_req{onresponse=Ret}) -> Ret;
g(p_headers, #http_req{p_headers=Ret}) -> Ret;
g(path, #http_req{path=Ret}) -> Ret;
g(path_info, #http_req{path_info=Ret}) -> Ret;
g(peer, #http_req{peer=Ret}) -> Ret;
g(pid, #http_req{pid=Ret}) -> Ret;
g(port, #http_req{port=Ret}) -> Ret;
g(qs, #http_req{qs=Ret}) -> Ret;
g(qs_vals, #http_req{qs_vals=Ret}) -> Ret;
g(resp_body, #http_req{resp_body=Ret}) -> Ret;
g(resp_headers, #http_req{resp_headers=Ret}) -> Ret;
g(resp_state, #http_req{resp_state=Ret}) -> Ret;
g(socket, #http_req{socket=Ret}) -> Ret;
g(transport, #http_req{transport=Ret}) -> Ret;
g(version, #http_req{version=Ret}) -> Ret.
Instead of
g(Field, Req) -> Req#http_req.Field.
Better control over access? You can still do it in the guard if you need to.
I'm sure you'll tell me this should be generated? That's neither clear
nor practical. And the generated code would likely not give good control
over access either anyway.
> Erlang needs dynamic field access like oysters need shooting-sticks.
For records I agree, for almost anything else (dict | sets | proplists |
maps | ...) I don't. Especially more so in Erlang.
You're being very affirmative over what people do or don't need, but you
seem to forget the one thing that people need the most: getting things
done. Perhaps a solution is slightly more prone to some kinds of bugs,
however making it harder to do something is as likely to create bugs.
Erlang is wonderful in that you can easily contain bugs to the local
process or group of processes, so I don't really see why we wouldn't
want to have more productive solutions. (And yes, productivity is also
subjective.)
--
Loïc Hoguin
Erlang Cowboy
Nine Nines
http://ninenines.eu
More information about the erlang-questions
mailing list