Re: Modelling in Clojure

2014-10-24 Thread Jirka Daněk
On Thursday, October 16, 2014 11:19:32 PM UTC+2, Tom Oram wrote: In Clojure, would you consider hiding the data behind a set of specialised functions to create, access and use it? Or would you just pass the primitive string/map/vector/whatever about and work on it directly? Stuart Sierra

Re: Modelling in Clojure

2014-10-23 Thread Daniel
To their a wrench in the works, keywords are functions that look themselves up in a map. Therefore, a traditional map is just as much api as data, and map values can be functions too, blurring the lines between static and computed values. So, you know, have fun with that. -- You received

Re: Modelling in Clojure

2014-10-23 Thread James Reeves
On 21 October 2014 01:23, Daniel doubleagen...@gmail.com wrote: To their a wrench in the works, keywords are functions that look themselves up in a map. Therefore, a traditional map is just as much api as data I'm not sure why you think one follows from the other. - James -- You received

Re: Modelling in Clojure

2014-10-22 Thread Linus Ericsson
Jason, the summary is good, but I'm missing the more efficient data structure array-map that probably wastes less space than the hash-map for the same size of object. [1] Also Zach Tellman has made some effort with clj-tuple which however use indexes, not keys. [2] [1]

Re: Modelling in Clojure

2014-10-22 Thread Phillip Lord
James Reeves ja...@booleanknot.com writes: Sure, laziness feels like a subset of UAP. Regardless, we have a nice example in Clojure, where we not distinguishing between data and computation allows us to do something nice. Yes... I agree it allows us to do something, but let's agree to

Re: Modelling in Clojure

2014-10-22 Thread James Reeves
On 22 October 2014 08:24, Linus Ericsson oscarlinuserics...@gmail.com wrote: 2014-10-22 6:25 GMT+02:00 Jason Wolfe ja...@w01fe.com: Maybe this post from would be of use? https://github.com/Prismatic/eng-practices/blob/master/clojure/20130926-data-representation.md the summary is good,

Re: Modelling in Clojure

2014-10-22 Thread James Reeves
On 22 October 2014 10:01, Phillip Lord phillip.l...@newcastle.ac.uk wrote: James Reeves ja...@booleanknot.com writes: Regardless, we have a nice example in Clojure, where we not distinguishing between data and computation allows us to do something nice. Yes... I agree it allows us to

Re: Modelling in Clojure

2014-10-22 Thread Fluid Dynamics
On Wednesday, October 22, 2014 6:09:04 AM UTC-4, James Reeves wrote: On 22 October 2014 10:01, Phillip Lord philli...@newcastle.ac.uk javascript: wrote: James Reeves ja...@booleanknot.com javascript: writes: Regardless, we have a nice example in Clojure, where we not distinguishing

Re: Modelling in Clojure

2014-10-22 Thread James Reeves
On 22 October 2014 14:32, Fluid Dynamics a2093...@trbvm.com wrote: On Wednesday, October 22, 2014 6:09:04 AM UTC-4, James Reeves wrote: No, I mean unrestricted uniform access. Clojure's laziness is restricted to seqs Not quite; there's also delay and force, and it's possible to use these

Re: Modelling in Clojure

2014-10-22 Thread Stephen Gilardi
Clojure's laziness is restricted to seqs and is guaranteed to always produce the same value for the same field. Nope: = (def foo (int-array [1 2 2 5 9 3])) #'user/foo = (def bar (seq foo)) #'user/bar = bar (1 2 2 5 9 3) = (aset foo 3 3) 3 = bar (1 2 2 3 9 3) There’s no laziness

Re: Modelling in Clojure

2014-10-22 Thread Ambrose Bonnaire-Sergeant
On Wed, Oct 22, 2014 at 9:32 AM, Fluid Dynamics a2093...@trbvm.com wrote: and is guaranteed to always produce the same value for the same field. Nope: = (def foo (int-array [1 2 2 5 9 3])) #'user/foo = (def bar (seq foo)) #'user/bar = bar (1 2 2 5 9 3) = (aset foo 3 3) 3 = bar (1 2

Re: Modelling in Clojure

2014-10-22 Thread Fluid Dynamics
On Wednesday, October 22, 2014 12:10:30 PM UTC-4, Ambrose Bonnaire-Sergeant wrote: On Wed, Oct 22, 2014 at 9:32 AM, Fluid Dynamics a209...@trbvm.com javascript: wrote: and is guaranteed to always produce the same value for the same field. Nope: = (def foo (int-array [1 2 2 5 9 3]))

Re: Modelling in Clojure

2014-10-22 Thread Jozef Wagner
Not every ISeq is lazy. In this case the seq is not lazy but is backed by a mutable array, thus the mentioned behavior. Jozef On Wednesday, October 22, 2014 6:41:34 PM UTC+2, Fluid Dynamics wrote: On Wednesday, October 22, 2014 12:10:30 PM UTC-4, Ambrose Bonnaire-Sergeant wrote: On Wed,

Re: Modelling in Clojure

2014-10-22 Thread Ambrose Bonnaire-Sergeant
I missed this in the sequence spec http://clojure.org/sequences: When seq is used on native Java arrays, changes to the underlying array will be reflected in the seq - you must copy the source array to get full immutability. I understand the rationale, still quite shocking. Ambrose On Wed, Oct

Re: Modelling in Clojure

2014-10-22 Thread Fluid Dynamics
On Wednesday, October 22, 2014 4:51:23 PM UTC-4, Ambrose Bonnaire-Sergeant wrote: I missed this in the sequence spec http://clojure.org/sequences: When seq is used on native Java arrays, changes to the underlying array will be reflected in the seq - you must copy the source array to get

Re: Modelling in Clojure

2014-10-22 Thread Ambrose Bonnaire-Sergeant
There is no point considering workarounds (but thanks either way). Every line of Clojure code near a call to `seq` has local assumptions about an immutable data structure. The implications run deep. If this issue is going to be tackled, ArraySeq needs to be made immutable. I'll continue this

Re: Modelling in Clojure

2014-10-21 Thread Jirka Daněk
I asked the question Lightweight data modeling vs traditional classes https://programmers.stackexchange.com/questions/260309/lightweight-data-modeling-vs-traditional-classes on Programmers.StackExchange three days ago. I am happy I found this discussion, because the evil moderators at SE hate

Re: Modelling in Clojure

2014-10-21 Thread Phillip Lord
James Reeves ja...@booleanknot.com writes: Which is nice and simple, yes. And has negative consequences in terms of extensibility. I understand if you are happy with this compromise. But it is a compromise. I don't disagree, but I do consider the compromise to be a minor one. UAP has huge

Re: Modelling in Clojure

2014-10-21 Thread Tom Oram
I think I've not got a much better idea of data as the API concept. What I'm still wandering is where do you do the validation of the data. For example, say a customer has a name, email and favourite colour. This could be represented as a map like so: {:name Tom, :email t...@whatever.com,

Re: Modelling in Clojure

2014-10-21 Thread James Reeves
On 21 October 2014 12:52, Phillip Lord phillip.l...@newcastle.ac.uk wrote: Okay. I can give you a very concrete example, and one where I think that it probably has been actually useful to you. Imagine you write the following piece of code: (first l) This returns a value. If we obeyed the

Re: Modelling in Clojure

2014-10-21 Thread James Reeves
I think there's should be a strong distinction between data that comes from an external source, and data that comes from an internal source. External data should be verified as soon as it comes in. There should be a thorough check at the top level that ensures everything is correct before

Re: Modelling in Clojure

2014-10-21 Thread Tom Oram
Thanks for such a great reply James, it was exactly the answer I was hoping for. Also, the point about functions only checking the part of the map that are interested in is something which makes perfect sense but I'd not even considered. Having come from the idea that the data should be

Re: Modelling in Clojure

2014-10-21 Thread Mike Haney
I can't remember if someone posted this already, and the thread is too long and I am too lazy to go back and check, so I apologize if it's already been mentioned. Anyway, I found this talk very helpful when I started learning Clojure, getting used to data-oriented thinking:

Re: Modelling in Clojure

2014-10-21 Thread Phillip Lord
James Reeves ja...@booleanknot.com writes: On 21 October 2014 12:52, Phillip Lord phillip.l...@newcastle.ac.uk wrote: Okay. I can give you a very concrete example, and one where I think that it probably has been actually useful to you. Imagine you write the following piece of code:

Re: Modelling in Clojure

2014-10-21 Thread James Reeves
On 21 October 2014 17:15, Phillip Lord phillip.l...@newcastle.ac.uk wrote: James Reeves ja...@booleanknot.com writes: So you're saying laziness and UAP are the same thing in your view? I am saying that UAP enables you to implement laziness freely. Sure, laziness feels like a subset of

Re: Modelling in Clojure

2014-10-21 Thread Tom Oram
@Mike Hanley - Really great video, thanks for the link! On Tuesday, 21 October 2014 15:26:35 UTC+1, Mike Haney wrote: I can't remember if someone posted this already, and the thread is too long and I am too lazy to go back and check, so I apologize if it's already been mentioned. Anyway,

Re: Modelling in Clojure

2014-10-21 Thread Jason Wolfe
Hi Tom, Maybe this post from would be of use? https://github.com/Prismatic/eng-practices/blob/master/clojure/20130926-data-representation.md It's my best attempt (albeit a year or so old) to answer many of these questions. Happy to answer questions if you've got them. Cheers, Jason On

Re: Modelling in Clojure

2014-10-20 Thread Phillip Lord
James Reeves ja...@booleanknot.com writes: On 17 October 2014 16:21, Phillip Lord phillip.l...@newcastle.ac.uk wrote: http://en.wikipedia.org/wiki/Uniform_access_principle To my knowledge, Clojure cannot do this. Yes, Clojure pretty much rejects the idea of uniform access. I don't think

Re: Modelling in Clojure

2014-10-20 Thread Phillip Lord
Fluid Dynamics a2093...@trbvm.com writes: I don't know who is the outlier. The point is that Scala, for instance, has explicit support to hide the distinction between accessing a value and computing a value. The point is to support the uniform access principle.

Re: Modelling in Clojure

2014-10-20 Thread Phillip Lord
James Reeves ja...@booleanknot.com writes: On 18 October 2014 08:28, Mark Engelberg mark.engelb...@gmail.com wrote: Yeah, it's hard to deny the convenience of Clojure's keyword lookups and standard assoc mechanism for getting and setting stored values, but I think Bertrand Meyer's Uniform

Re: Modelling in Clojure

2014-10-20 Thread Gary Verhaegen
On Monday, 20 October 2014, Phillip Lord phillip.l...@newcastle.ac.uk wrote: Interesting. So, if you resolve http://www.clojure.org, is this data or is it computed? You're dereferencing a ref (url) to get an immutable value (string). Maybe it would be worth exploring ways to implement IDeref

Re: Modelling in Clojure

2014-10-20 Thread James Reeves
On 20 October 2014 12:23, Phillip Lord phillip.l...@newcastle.ac.uk wrote: James Reeves ja...@booleanknot.com writes: Yes, Clojure pretty much rejects the idea of uniform access. I don't think it does. I think it just does not support it which is a somewhat different thing. I thought it

Re: Modelling in Clojure

2014-10-20 Thread Phillip Lord
James Reeves ja...@booleanknot.com writes: Yes, Clojure pretty much rejects the idea of uniform access. I don't think it does. I think it just does not support it which is a somewhat different thing. I thought it was pretty clear that Clojure prefers data over APIs. The uniform access

Re: Modelling in Clojure

2014-10-20 Thread James Reeves
On 20 October 2014 14:02, Phillip Lord phillip.l...@newcastle.ac.uk wrote: The uniform access principle is about having uniform access to data and APIs. It's not about prefering one or the other. Right, but Clojure *does* heavily prefer data over APIs, and therein lies the conflict. Yes,

Re: Modelling in Clojure

2014-10-20 Thread Phillip Lord
James Reeves ja...@booleanknot.com writes: Yes, which is what I have done, of course. Now it won't work in any IDE which looks for the docstring as :doc metadata. It is totally unextensible. I do not think that this is good. Clojure prefers simple solutions over easy solutions. A nice

Re: Modelling in Clojure

2014-10-20 Thread Brandon Bloom
Well, the question is, where does this additional complexity come from. In Java, it results in enormous quantities of boilerplate get/set methods. In Scala, these are autocoded away. Boilerplate isn't complexity: It's inefficiency. I'll grant that it creates complexity-potential-energy

Re: Modelling in Clojure

2014-10-20 Thread James Reeves
On 20 October 2014 17:08, Phillip Lord phillip.l...@newcastle.ac.uk wrote: James Reeves ja...@booleanknot.com writes: Clojure prefers simple solutions over easy solutions. A nice aphorism sometimes, but content free in this case, I think. Well, no... The whole point is that simple and

Re: Modelling in Clojure

2014-10-19 Thread Alex Baranosky
I've maintained 5+ year-old Clojure applications and the Uniform Access Principle was not a concern for me. Bigger concerns for me were the Single-Responsibility Principle, and conversely, the Big Ball of Mud Anti-pattern. But I think these are both concerns on any large, old program in any

Re: Modelling in Clojure

2014-10-18 Thread Mark Engelberg
Yeah, it's hard to deny the convenience of Clojure's keyword lookups and standard assoc mechanism for getting and setting stored values, but I think Bertrand Meyer's Uniform Access Principle reflects some pretty deep thinking about the kinds of complications that arise in maintaining large

Re: Modelling in Clojure

2014-10-18 Thread Tom Oram
While this discussing has taken a slight tangent from my original question, it's been a very interesting read. Thanks for all your thoughts everyone. You guys rock! On 18 October 2014 08:28, Mark Engelberg mark.engelb...@gmail.com wrote: Yeah, it's hard to deny the convenience of Clojure's

Re: Modelling in Clojure

2014-10-18 Thread James Reeves
On 18 October 2014 08:28, Mark Engelberg mark.engelb...@gmail.com wrote: Yeah, it's hard to deny the convenience of Clojure's keyword lookups and standard assoc mechanism for getting and setting stored values, but I think Bertrand Meyer's Uniform Access Principle reflects some pretty deep

Re: Modelling in Clojure

2014-10-18 Thread Chris Ford
James might be too modest to mention this as an exemplar as he's the maintainer, but for me, Ring https://github.com/ring-clojure/ring is a great example of the success of data-as-API. HTTP requests are represented as a nested map with well-known keys, and middleware works with these fields or

Re: Modelling in Clojure

2014-10-18 Thread Luc Préfontaine
+1. Two years ago we went all data driven here. We stripped the code size and complexity by a huge factor. All data encapsulation code was sent to the trash can. Our processing is driven by data more than by code. We ended up with a significant increase in generic code not linked to the

Re: Modelling in Clojure

2014-10-18 Thread Mark Engelberg
I think all of James' points about the proven value of structuring an application primarily around data rather than a complex API are right on point. It is one of the things I love about the Clojure philosophy. But there's nothing about the value of data-driven development that requires data

Re: Modelling in Clojure

2014-10-18 Thread Nahuel Greco
Maybe we need some sort of lazy map where: (def m (assoc-computed {:first-name Robert :last-name Plankton} :full-name #(str (:first-name %) (:last-name % ;; will call the function to compute the value and will memoize it: (:full-name m) ;; now the memoized value is

Re: Modelling in Clojure

2014-10-18 Thread James Reeves
On 18 October 2014 21:02, Mark Engelberg mark.engelb...@gmail.com wrote: I think all of James' points about the proven value of structuring an application primarily around data rather than a complex API are right on point. It is one of the things I love about the Clojure philosophy. But

Re: Modelling in Clojure

2014-10-18 Thread Brandon Bloom
I don't know who is the outlier. The point is that Scala, for instance, has explicit support to hide the distinction between accessing a value and computing a value. The point is to support the uniform access principle. http://en.wikipedia.org/wiki/Uniform_access_principle In one

Re: Modelling in Clojure

2014-10-17 Thread Tom Oram
Wow! Thanks for all the replies everyone! I had a suspicion that the general response would be that I was thinking too much in terms of OOP. I'm going to try and go more with the approach suggested in the replies (it's a mental struggle more than a technical one because I've definitely trained

Re: Modelling in Clojure

2014-10-17 Thread Tom Oram
Oh also, can anyone recommend a really well designed OS application I can take a look at and study the code? On Thursday, 16 October 2014 22:19:32 UTC+1, Tom Oram wrote: Hello Clojure people, First up, apologies because this is going to be a long message. Howver, if you do have the time to

Re: Modelling in Clojure

2014-10-17 Thread Phillip Lord
Mark Engelberg mark.engelb...@gmail.com writes: But let's say later you decide you want your data model to be {:first-name Alice, :last-name Beasley, :email al...@example.com}, and you want to change name to be a computed value that concatenates first and last names -- this is going to break

Re: Modelling in Clojure

2014-10-17 Thread James Reeves
On 17 October 2014 05:47, Rui Yang ryang@gmail.com wrote: I am new to clojure. My question how to handle version if we expose data directly as api, any schema change will break the api which may impact third party users. Just treat breaking schema changes in the same way you'd treat

Re: Modelling in Clojure

2014-10-17 Thread James Reeves
On 17 October 2014 12:14, Phillip Lord phillip.l...@newcastle.ac.uk wrote: Actually, I think that this is a real problem with Clojure, and with data access. It is very hard to change between accessing a var as a value and through calling a value. Curiously, this is something I don't think

Re: Modelling in Clojure

2014-10-17 Thread Luc Préfontaine
Hi Phil, At some point in time after a prolonged exposure to Clojure, my mind shifted, I now think about my program flow as values, not containers being passed along. I take the problem the reverse way to find out if there's a need for a var vs a fn and state lifecyle. Here's a short summary of

Re: Modelling in Clojure

2014-10-17 Thread Phillip Lord
James Reeves ja...@booleanknot.com writes: Actually, I think that this is a real problem with Clojure, and with data access. It is very hard to change between accessing a var as a value and through calling a value. Curiously, this is something I don't think I've ever run into. Perhaps

Re: Modelling in Clojure

2014-10-17 Thread James Reeves
On 17 October 2014 16:21, Phillip Lord phillip.l...@newcastle.ac.uk wrote: http://en.wikipedia.org/wiki/Uniform_access_principle To my knowledge, Clojure cannot do this. Yes, Clojure pretty much rejects the idea of uniform access. When I first wrote the var, I thought it was going to be

Re: Modelling in Clojure

2014-10-17 Thread Fluid Dynamics
On Friday, October 17, 2014 11:22:22 AM UTC-4, Phillip Lord wrote: James Reeves ja...@booleanknot.com javascript: writes: Actually, I think that this is a real problem with Clojure, and with data access. It is very hard to change between accessing a var as a value and through

Re: Modelling in Clojure

2014-10-17 Thread Mars0i
On Thursday, October 16, 2014 11:53:42 PM UTC-5, puzzler wrote: In Clojure, non-computed fields are usually accessed directly by keyword, whereas computed fields require an actual API. This difference in access style complicates things if you want to change which things are stored versus

Modelling in Clojure

2014-10-16 Thread Tom Oram
Hello Clojure people, First up, apologies because this is going to be a long message. Howver, if you do have the time to read and respond, then I would be extremely grateful! Recently I've decided to give Clojure a proper go. Over the past year or so I've paid it a bit of attention: I've read

Re: Modelling in Clojure

2014-10-16 Thread James Reeves
Hi Tom, Clojure views software architecture in a fundamentally different way to object orientated languages. In some areas, Clojure best practice is diametrically opposite to OOP best practice. One of the key ideas of OOP is encapsulating data, but Clojure entirely rejects this. In Clojure, raw

Re: Modelling in Clojure

2014-10-16 Thread Mark Engelberg
On Thu, Oct 16, 2014 at 3:49 PM, James Reeves ja...@booleanknot.com wrote: {:name Alice, :email al...@example.com} At this point, stop. You have your data model. I think that coming from OO, the most disconcerting piece of Clojure's philosophy is that it is relatively rare in Clojure

Re: Modelling in Clojure

2014-10-16 Thread Sean Corfield
On Oct 16, 2014, at 5:08 PM, Mark Engelberg mark.engelb...@gmail.com wrote: But let's say later you decide you want your data model to be {:first-name Alice, :last-name Beasley, :email al...@example.com}, and you want to change name to be a computed value that concatenates first and last

Re: Modelling in Clojure

2014-10-16 Thread James Reeves
On 17 October 2014 01:08, Mark Engelberg mark.engelb...@gmail.com wrote: But let's say later you decide you want your data model to be {:first-name Alice, :last-name Beasley, :email al...@example.com}, and you want to change name to be a computed value that concatenates first and last names

Re: Modelling in Clojure

2014-10-16 Thread Armando Blancas
Sure, that's the theory behind encapsulation, but I'm not convinced there are many cases in practice where the API can remain consistent while the data changes. I'm not, either. Models that have little or no abstraction --basically aggregates of related items-- end up having APIs

Re: Modelling in Clojure

2014-10-16 Thread Rui Yang
I am new to clojure. My question how to handle version if we expose data directly as api, any schema change will break the api which may impact third party users. On Friday, 17 October 2014 15:23:10 UTC+11, Armando Blancas wrote: Sure, that's the theory behind encapsulation, but I'm not

Re: Modelling in Clojure

2014-10-16 Thread Atamert Ölçgen
Every programming language is a (somewhat) unique approach to programming. So they all have their ways. Java is best expressed using Java best practices. Python is best expressed using Python best practices. Of course Clojure too is best expressed using Clojure best practices. Having said that; I

Re: Modelling in Clojure

2014-10-16 Thread Mark Engelberg
Right, my point wasn't just about data change, it was more specifically about the addition or change of computed fields. In Clojure, non-computed fields are usually accessed directly by keyword, whereas computed fields require an actual API. This difference in access style complicates things if

Re: Modelling in Clojure

2014-10-16 Thread Atamert Ölçgen
On Fri, Oct 17, 2014 at 12:47 PM, Rui Yang ryang@gmail.com wrote: I am new to clojure. My question how to handle version if we expose data directly as api, any schema change will break the api which may impact third party users. You can't protect the consumers of your API. You publish