Fork me on GitHub
#clojure-dev
<
2018-11-26
>
Yehonathan Sharvit14:11:27

A question related to records: records implement most of the maps functionalities: get, assoc, keys etc… but they cannot be called as functions like maps Is there a special reason for this “limitation” of records?

potetm15:11:18

@viebel I’m not an authority on this at all, but there are a couple of things that jump out for me: 1) records can implement protocols, so this already means there’s a variety of semantics associated w/ a record (not just get/assoc/et al). 2) More generally, it’s unclear what the semantics of invoking an arbitrary type should be.

Alex Miller (Clojure team)15:11:48

Records are information structures so designed to optimize keyword lookup

Alex Miller (Clojure team)15:11:11

They are not generic key to value lookup tables like generic maps

Alex Miller (Clojure team)15:11:22

Which is the use case for IFn

Yehonathan Sharvit16:11:34

How would you explain the main conceptual differences between a Clojure Record and a Java (or other OOP language) object?

borkdude16:11:27

record is an immutable piece of information. a Java object can be anything

Yehonathan Sharvit16:11:00

But records have also methods

borkdude16:11:19

oh right. yeah..

borkdude16:11:52

should the carmine example from above have chosen deftype or is defrecord ok there?

bronsa16:11:17

to me that screams deftype

borkdude17:11:45

What about the component library? It uses defrecord for information from the program domain.

4
4
hiredman17:11:18

component defrecords are immutable things (which is why start and stop have to return the updated component) where subparts can be updated in dependency order (which exists but isn't often used in practice), it could invent its own abstraction to cover that kind of thing, but it would just be another definition of a map interface

borkdude17:11:03

so it seems the question is not: is it domain or program information, but do you need something map-like

hiredman17:11:37

with a little bit of retro fitting, you can make component use regular maps, which is great, I would prefer those to defrecords, but things get kind of messy when you want to define interfaces between things without protocols, you end up rolling your own thing with collections of functions, or groups of multimethods, each of which have there own downsides (collections of functions might not actually be that bad, but multimethods are global things which makes them a pain for things like testing)

hiredman17:11:08

is it data or not? dependencies between parts of your program is data, your socket connection to a database is maybe not

mpenet18:11:36

I have done that for the pixie port of component

mpenet18:11:14

Actually now that I looked to that code the issue was something else: records without ext in pixie so systems had to be maps etc etc. Totally different

mpenet18:11:26

It's quite easy. You can just use meta when necessary.

Yehonathan Sharvit18:11:53

@mpenet can you give an example of “usage of meta when necessary”?

mpenet18:11:20

component support maps so nothing special. But if you d wanted to fork it and make it work without records you could abuse meta to store "type" info, which is similar to the new protocols with metadata dispatch we have now

hiredman18:11:41

you actually don't have to fork it

mpenet18:11:15

start/stop do not know on what to dispatch if I recall

hiredman18:11:19

you can use your own custom start and stop functions

hiredman18:11:00

at a previous job we did that, and it was all multimethod based

mpenet18:11:12

Right, sure you can do it this way too

hiredman18:11:14

there is a #component which might be a better place for this

Alex Miller (Clojure team)23:11:57

yeah. not gonna fix it now…

👍 4