Erlang maps syntax

154 views
Skip to first unread message

Duncan McGreggor

unread,
Mar 22, 2014, 12:01:11 AM3/22/14
to lisp-flavo...@googlegroups.com
Speaking of "homework" (referring to the last email...),

I'm working on a write-up of hashmap/hashtable syntaxes used in other Lisps. My purposes are manifold:
 * refresh my muscle memory, feel what it's like to type/work with maps in other Lisps
 * identify great features we may want to duplicate
 * identify cumbersome user/dev experiences we may want to avoid
 * put a common set of examples out there we can all refer to in our discussion

What this work doesn't aim to do: propose a new syntax :-)

Hopefully the forth-coming post will start up some good conversations around this on the list, and we can take it from there, as interested members of the LFE community...

I hope to have this ready within a few days...

d

P.S. I'm looking at CL, Scheme (Racket), Clojure, map-like functionality in LFE, and Joe's blog post about Erlang maps.

Duncan McGreggor

unread,
Mar 22, 2014, 1:39:30 AM3/22/14
to lisp-flavo...@googlegroups.com
More this weekend ...

d

Duncan McGreggor

unread,
Mar 22, 2014, 2:51:45 PM3/22/14
to lisp-flavo...@googlegroups.com
I've added shen, open list, and an LFE orddict example. I didn't bother to add a Chicken Scheme example, since it was so similar to Racket. That being said, the Chicken Scheme API is one of the better ones I've seen.

Starting to have some thoughts, now that I've walked through these...

d

Sean Chalmers

unread,
Mar 22, 2014, 9:27:43 PM3/22/14
to lisp-flavo...@googlegroups.com
Thanks for the comparison Duncan !! I'd not used anything other than Clojure maps to really get a feel for their usage and syntax..

What I enjoy from the Clojure maps:

Define the map:
(def my-map {:foo "bar" :took "fool" :tuna "salmon"})

The keys are defined as functions that can return the value they refer to on the map.
> (:foo my-map)
"bar"
> (:took my-map)
"fool"

When you're pattern matching or destructuring them you can use this technique to cherry pick the ones your interested in.

(let [{:keys [tuna took]} my-map]
  (apply str took tuna))

or you can do this:

(let [{foo :foo fish :tuna} my-map]
  (apply str foo fish))

I don't think we can get away with the cleverness of using the keys as functions to access the elements of the map. Or at least I can't immediately think of a way to do it.. Probably at 2am when I don't have a notepad to hand. -.-

I expect we can probably become pretty creative when it comes to the pattern matching or destructuring though. :D

I like Robs idea of ensuring we have the basics there first with:

make-map (like make-record)
map-get
map-set

Do we need a defmap ?

Because from there we can create the functionality surrounding it using all of the built in maps:foo() capability and Lispy deliciousness. I know it's kinda boring but maybe once we have them in, we can then start to really mess with what's capable, and we'll be able to see what's missing?

I really really want to keep the ':=' and '=>' syntax, I think they just nailed that. But first things first. :)

Sean

Duncan McGreggor

unread,
Mar 23, 2014, 12:10:31 AM3/23/14
to lisp-flavo...@googlegroups.com
On Sat, Mar 22, 2014 at 8:27 PM, Sean Chalmers <sclhi...@gmail.com> wrote:
Thanks for the comparison Duncan !! I'd not used anything other than Clojure maps to really get a feel for their usage and syntax..

What I enjoy from the Clojure maps:

Define the map:
(def my-map {:foo "bar" :took "fool" :tuna "salmon"})

The keys are defined as functions that can return the value they refer to on the map.
> (:foo my-map)
"bar"
> (:took my-map)
"fool"

When you're pattern matching or destructuring them you can use this technique to cherry pick the ones your interested in.

(let [{:keys [tuna took]} my-map]
  (apply str took tuna))

or you can do this:

(let [{foo :foo fish :tuna} my-map]
  (apply str foo fish))

I don't think we can get away with the cleverness of using the keys as functions to access the elements of the map. Or at least I can't immediately think of a way to do it.. Probably at 2am when I don't have a notepad to hand. -.-

I was thinking of playing with this... I think we could do it, because LFE is a Lisp-2. I think it would be possible, whenever a map was created, to generate a macro with the same name as the defined map (similar to how records are done in LFE), and calling that macro with a key could then return the value of the associated map.

d

 

--
You received this message because you are subscribed to the Google Groups "Lisp Flavoured Erlang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lisp-flavoured-e...@googlegroups.com.
To post to this group, send email to lisp-flavo...@googlegroups.com.
Visit this group at http://groups.google.com/group/lisp-flavoured-erlang.
For more options, visit https://groups.google.com/d/optout.

rvirding

unread,
Mar 23, 2014, 12:52:30 PM3/23/14
to lisp-flavo...@googlegroups.com

On Sunday, March 23, 2014 5:10:31 AM UTC+1, Duncan McGreggor wrote:

On Sat, Mar 22, 2014 at 8:27 PM, Sean Chalmers <sclhi...@gmail.com> wrote:
Thanks for the comparison Duncan !! I'd not used anything other than Clojure maps to really get a feel for their usage and syntax..

What I enjoy from the Clojure maps:

Define the map:
(def my-map {:foo "bar" :took "fool" :tuna "salmon"})

The keys are defined as functions that can return the value they refer to on the map.
> (:foo my-map)
"bar"
> (:took my-map)
"fool"

When you're pattern matching or destructuring them you can use this technique to cherry pick the ones your interested in.

(let [{:keys [tuna took]} my-map]
  (apply str took tuna))

or you can do this:

(let [{foo :foo fish :tuna} my-map]
  (apply str foo fish))

I don't think we can get away with the cleverness of using the keys as functions to access the elements of the map. Or at least I can't immediately think of a way to do it.. Probably at 2am when I don't have a notepad to hand. -.-

I was thinking of playing with this... I think we could do it, because LFE is a Lisp-2. I think it would be possible, whenever a map was created, to generate a macro with the same name as the defined map (similar to how records are done in LFE), and calling that macro with a key could then return the value of the associated map.
 
I think this is basically impossible as a map has no name, it is nameless. This is one of the features of maps. You *could* add a "name" field but that would be self-defeating as it would make it incompatible with Erlang.

I would be interested to learn *how* they implement this in Clojure. Do they have "keywords"? Are atoms starting with a ':' specially treated as keywords? If so you could view each keyword as a function which takes a map as an argument and and returns the value of its namesake. That is something like how CL handles symbols starting with a ':', they are defined in the keyword package. That is also the solution they use for being able to share symbols painlessly between various packages, they put them in keyword package.

We can't do it that way. Especially as the keys in a map can be anything, not just atoms. So we have to some special symbols to use in the "function" position when we access maps. That is why I went record-like with make-map, match-map etc. I don't know yet if these should be macros or what. I will have to look and see how maps are done in Core erlang to work this out. Maybe the basic primitives have to become part of the language in some way. We can always wrap them in macros later to make them nicer.

We now have different map syntax threads. Can we use this one for both discussions?

Robert

Reply all
Reply to author
Forward
0 new messages