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
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
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
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]
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
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,
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
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
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
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
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
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]))
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,
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
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
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
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
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
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,
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
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
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
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:
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:
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
@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,
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
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
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.
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
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
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
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
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,
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
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
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
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
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
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
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
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
+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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
67 matches
Mail list logo