announcements

Project/library announcements ONLY - use threaded replies for discussions. Do not cross post here from other channels. Consider #events or #news-and-articles for other announcements.
simongray 2021-01-04T00:58:27.436600Z

I compiled a list of Clojure resources for domain-specific languages and parsing: https://github.com/simongray/clojure-dsl-resources Suggestions are very welcome. I’m just a lowly programmer trying to educate myself about this space.

14👍2✔️
borkdude 2021-01-04T08:47:33.438800Z

Made some suggestions: https://github.com/simongray/clojure-dsl-resources/issues/1

ikitommi 2021-01-04T09:12:07.439400Z

maybe routing libs should be included? compojure, bidi, reitit etc.

2👍
simongray 2021-01-04T09:42:38.439700Z

@ikitommi I’ll consider that. I don’t think they should go in the regular data-based/classic DSL subcategories, but perhaps they could get a separate section?

ikitommi 2021-01-04T11:29:33.445900Z

:thinking_face: both ok, I think. Would be easier to compare if they were under same category.

borkdude 2021-01-04T11:33:53.446100Z

imo, routing dsls are just as dsl as html dsls

eggsyntax 2021-01-04T18:42:44.450100Z

Great to have a centralized list of Clojure DSL stuff -- thanks for putting it together!

simongray 2021-01-04T20:47:15.453400Z

@eggsyntax NP! They’re a useful way for me to get an overview too.

1👍
simongray 2021-01-04T20:52:07.453600Z

@borkdude Part of the tricky part of defining a DSL in Clojure is that everything blends together. I think there’s a meaningful distinction with the way one uses (what I would call) a DSL and then configuration for a web service. The former is used adhoc in various places, while the latter is often has a much simpler grammar and is more situated in the application process.

simongray 2021-01-04T20:55:59.453800Z

Is a hash map used to describe a web service a DSL? I would argue that it definitely could be, but only if it’s used in a distinctly different way from how hash maps are typically used. A DSL sort of requires a grammar that is different from the typical usage of language constructs.

borkdude 2021-01-04T20:59:38.454100Z

I'm not so sure where to draw the line. The below stuff looks like hiccup to me, but for routing (this is bidi):

["<http://localhost:8080>"
 [[["/users/" :user-id]
   [["/topics" [["" :topics] ["/bulk" :topic-bulk]]]]]
  [["/topics/" :topic] [["" :private-topic]]]
  ["/schemas" :schemas]
  [["/orgs/" :org-id] [["/topics" :org-topics]]]]]

borkdude 2021-01-04T21:01:25.454300Z

Often a distinction is made between eDSLs (using language constructs) and DSLs (usually in text). Almost everything in Clojure is an eDSL if you use data to describe something

simongray 2021-01-04T21:24:04.455Z

I mean that is definitely different from typical usage of vectors, but all it really does is define a tree of routes. Most of what the more data-oriented web libraries do is to combine something like that bidi example with some regular old maps. Is that really a DSL? I think it’s great that Clojure is so focused on data > function > macros, but I think something that is singular in purpose and which can be parsed in a few lines of code can hardly be called a DSL. Something like Hiccup is obviously simple-looking too, but it also comes with - obviously inherited from HTML and XML - a very rich set of semantics and additional syntax, even though on the surface it’s just a bunch of [:tag {:attr ...} [:child ...]]. When you write Hiccup, you’re painting a web page. When you write a bidi route, you’re writing a bidi route.

simongray 2021-01-04T21:25:12.455200Z

Not knocking on bidi, reitit, pedestal, compojure and so on AT ALL, but I think they’re quite different.

eggsyntax 2021-01-04T21:26:10.455400Z

> Often a distinction is made between eDSLs (using language constructs) and DSLs (usually in text). Almost everything in Clojure is an eDSL if you use data to describe something Seems worth mentioning here (for anyone who hasn't read it) Martin Fowler's book Domain Specific Languages, which I believe initially coined that external/internal DSL distinction, and which IMHO is indispensable for anyone diving into DSLs.

1👍
simongray 2021-01-04T21:28:23.455800Z

Thanks, I’ll check it out 🙂

simongray 2021-01-04T21:29:31.456Z

(on to the Tsundoku pile it goes :P)

1😆
borkdude 2021-01-04T21:35:17.456300Z

@simongray I still don't really see the difference. The interpreter (or compiler) for reitit routes is quite sophisticated, althought their notation is very simple. So yeah, you could argue, is JSON/YAML/hiccup vector/maps config a DSL when there is a complex interpreter behind it, or what makes the DSL a DSL in that case?

borkdude 2021-01-04T21:37:23.456700Z

Is a Dockerfile a DSL because of the machinery behind it or because of the superficial syntax? And what if you write this Dockerfile in JSON or YAML, is it then a config file or still a DSL?

simongray 2021-01-04T21:54:34.457300Z

I would definitely say that a Dockerfile is a DSL since there are both very specific semantics and syntax involved and the purpose of a Dockerfile is varied enough that I would call it a distinct language. If you write a Dockerfile in a different language, then yes, that’s a DSL too, because you’re still writing using the Docker semantics and some slightly different syntax. At some point a cut has to be made, though. What about a path in a file system? Is that a DSL? I mean, it is a language of sorts. You can compose layers of file system navigation using slashes and there are operators, e.g. .. to backtrack. But all you’re really doing with this language is define routes - kinda like bidi. So using a loose definitions of what makes a DSL, a file path is a DSL and a bidi route is a DSL too. To me, a DSL is not just something that does one very simple thing. If we’re being really pedantic about it, sure, we could always define a DSL to be that. I think that’s setting the bar a bit too low. There has to be cutoff point. Yours is definitely in a different place than mine and that’s okay :-)

simongray 2021-01-04T22:00:11.457700Z

Obviously, DSLs are usually meant to do very specific things, so I’m not saying that the purpose of the DSL can’t be simple, but if its grammar is incredibly basic too… then the number of items in the list will definitely need to be of a different magnitude entirely. I’m not sure it would be fit for the purpose I had for it any longer (documenting DSLs in Clojure and tools for making them).

simongray 2021-01-04T22:02:11.458100Z

That said, I am definitely considering adding a separate section for data-oriented configuration and alike, since it’s so common in Clojure.

borkdude 2021-01-04T22:03:11.458300Z

So is deps.edn a DSL: the machinery behind it is certainly not trivial, but the data format is "just EDN". Same with writing Docker semantics in JSON. It's very blurry.

simongray 2021-01-04T22:03:53.458500Z

It’s definitely blurry. I already have a disclaimer in the list about that > In either case, a supposed DSL could just as easily be considered a creative use of existing language features or a particularly well-designed API.

borkdude 2021-01-04T22:04:14.458700Z

Thanks for the interesting discussion :)

simongray 2021-01-04T22:04:35.458900Z

You too. 😉 thanks for making cool stuff.

simongray 2021-01-04T22:47:04.459100Z

@ikitommi @borkdude here’s where I ended up putting it https://github.com/simongray/clojure-dsl-resources#data-oriented-configuration

2021-01-05T18:29:03.471600Z

@simongray Minimallist is missing in the list.

2021-01-05T19:11:37.472200Z

@simongray Girouette might also be relevant for your list https://github.com/green-coder/girouette

simongray 2021-01-06T01:01:40.474800Z

I added minimallist and vrac (under a new WIP section) since I found the idea really fascinating. On the other hand, I’m not really sure what girouette even does, so I left that out for now.

1👍
simongray 2021-01-06T01:04:05.475200Z

also, your taiwan example in the diffuse readme made me chuckle 🙂

1😅
2021-01-06T03:16:21.475800Z

Minimallist, Diffuse and Girouette were all developed with the purpose if being useful for Vrac - that's the underlying bigger picture. I will document and present Girouette next week, will send you the link once ready.

1🙏
emil0r 2021-01-04T08:29:58.438500Z

https://github.com/emil0r/ez-wire updated to 0.2.1 and new fancy documentation/demo showing the library in action. I also made a very bad logo o_O

3👍1
borkdude 2021-01-04T08:47:33.438800Z

Made some suggestions: https://github.com/simongray/clojure-dsl-resources/issues/1

ikitommi 2021-01-04T09:12:07.439400Z

maybe routing libs should be included? compojure, bidi, reitit etc.

2👍
simongray 2021-01-04T09:42:38.439700Z

@ikitommi I’ll consider that. I don’t think they should go in the regular data-based/classic DSL subcategories, but perhaps they could get a separate section?

2021-01-04T11:13:37.444800Z

https://github.com/henryw374/cljc.java-time version 0.1.12. • the major news is that you get helpful error messages (which are lacking in java.time). This is yet another reason to prefer this lib over plain interop with java.time - blogged about here: http://widdindustries.com/why-not-interop/ • also removed is the use of compile-target macros - which should speed things up for babashka users

34🦜13🎉
borkdude 2021-01-04T11:17:43.445300Z

(require '[babashka.deps :as deps])

(deps/add-deps '{:deps {cljc.java-time/cljc.java-time {:mvn/version "0.1.12"}}})

(require  '[cljc.java-time.local-date :as ld])

(def a-date (ld/parse "2019-01-01"))

(ld/plus-days a-date 99)
$ time bb /tmp/jtime.clj
#object[java.time.LocalDate 0x35095813 "2019-04-10"]
bb /tmp/jtime.clj   0.03s  user 0.02s system 89% cpu 0.049 total

2021-01-04T11:28:04.445700Z

cheers. yeah It's always going to be slower than (.parse java.time.LocalDate "2020-02-02") (about 3x on my machine) ,on bb because it has to interpret a bunch more code first etc

ikitommi 2021-01-04T11:29:33.445900Z

:thinking_face: both ok, I think. Would be easier to compare if they were under same category.

borkdude 2021-01-04T11:33:53.446100Z

imo, routing dsls are just as dsl as html dsls

borkdude 2021-01-04T11:43:26.446300Z

well, it's still fast :) and writing clojure can be more friendly

borkdude 2021-01-04T11:44:56.446500Z

I see about 10ms speedup between .11 and .12 on my machine

1
2021-01-04T11:46:55.446700Z

:thumbsup:

eggsyntax 2021-01-04T18:42:44.450100Z

Great to have a centralized list of Clojure DSL stuff -- thanks for putting it together!

slipset 2021-01-04T20:14:54.453Z

https://github.com/slipset/deps-deploy/ version 0.1.5 • support for -X, thanks to @rickmoynihan • support for private s3 repositories, also thanks to @rickmoynihan Thanks to @nichols1991 for pushing this release across the finish line and also for providing the upgrade to the s3-wagon dep so it also works with Java 10. Any errors are mine.

3🦜10🎉
2021-01-05T08:35:49.460800Z

Thanks for getting this merged!

simongray 2021-01-04T20:47:15.453400Z

@eggsyntax NP! They’re a useful way for me to get an overview too.

1👍
simongray 2021-01-04T20:52:07.453600Z

@borkdude Part of the tricky part of defining a DSL in Clojure is that everything blends together. I think there’s a meaningful distinction with the way one uses (what I would call) a DSL and then configuration for a web service. The former is used adhoc in various places, while the latter is often has a much simpler grammar and is more situated in the application process.

simongray 2021-01-04T20:55:59.453800Z

Is a hash map used to describe a web service a DSL? I would argue that it definitely could be, but only if it’s used in a distinctly different way from how hash maps are typically used. A DSL sort of requires a grammar that is different from the typical usage of language constructs.

borkdude 2021-01-04T20:59:38.454100Z

I'm not so sure where to draw the line. The below stuff looks like hiccup to me, but for routing (this is bidi):

["<http://localhost:8080>"
 [[["/users/" :user-id]
   [["/topics" [["" :topics] ["/bulk" :topic-bulk]]]]]
  [["/topics/" :topic] [["" :private-topic]]]
  ["/schemas" :schemas]
  [["/orgs/" :org-id] [["/topics" :org-topics]]]]]

borkdude 2021-01-04T21:01:25.454300Z

Often a distinction is made between eDSLs (using language constructs) and DSLs (usually in text). Almost everything in Clojure is an eDSL if you use data to describe something

simongray 2021-01-04T21:24:04.455Z

I mean that is definitely different from typical usage of vectors, but all it really does is define a tree of routes. Most of what the more data-oriented web libraries do is to combine something like that bidi example with some regular old maps. Is that really a DSL? I think it’s great that Clojure is so focused on data > function > macros, but I think something that is singular in purpose and which can be parsed in a few lines of code can hardly be called a DSL. Something like Hiccup is obviously simple-looking too, but it also comes with - obviously inherited from HTML and XML - a very rich set of semantics and additional syntax, even though on the surface it’s just a bunch of [:tag {:attr ...} [:child ...]]. When you write Hiccup, you’re painting a web page. When you write a bidi route, you’re writing a bidi route.

simongray 2021-01-04T21:25:12.455200Z

Not knocking on bidi, reitit, pedestal, compojure and so on AT ALL, but I think they’re quite different.

eggsyntax 2021-01-04T21:26:10.455400Z

> Often a distinction is made between eDSLs (using language constructs) and DSLs (usually in text). Almost everything in Clojure is an eDSL if you use data to describe something Seems worth mentioning here (for anyone who hasn't read it) Martin Fowler's book Domain Specific Languages, which I believe initially coined that external/internal DSL distinction, and which IMHO is indispensable for anyone diving into DSLs.

1👍
simongray 2021-01-04T21:28:23.455800Z

Thanks, I’ll check it out 🙂

simongray 2021-01-04T21:29:31.456Z

(on to the Tsundoku pile it goes :P)

1😆
borkdude 2021-01-04T21:35:17.456300Z

@simongray I still don't really see the difference. The interpreter (or compiler) for reitit routes is quite sophisticated, althought their notation is very simple. So yeah, you could argue, is JSON/YAML/hiccup vector/maps config a DSL when there is a complex interpreter behind it, or what makes the DSL a DSL in that case?

borkdude 2021-01-04T21:37:23.456700Z

Is a Dockerfile a DSL because of the machinery behind it or because of the superficial syntax? And what if you write this Dockerfile in JSON or YAML, is it then a config file or still a DSL?

simongray 2021-01-04T21:54:34.457300Z

I would definitely say that a Dockerfile is a DSL since there are both very specific semantics and syntax involved and the purpose of a Dockerfile is varied enough that I would call it a distinct language. If you write a Dockerfile in a different language, then yes, that’s a DSL too, because you’re still writing using the Docker semantics and some slightly different syntax. At some point a cut has to be made, though. What about a path in a file system? Is that a DSL? I mean, it is a language of sorts. You can compose layers of file system navigation using slashes and there are operators, e.g. .. to backtrack. But all you’re really doing with this language is define routes - kinda like bidi. So using a loose definitions of what makes a DSL, a file path is a DSL and a bidi route is a DSL too. To me, a DSL is not just something that does one very simple thing. If we’re being really pedantic about it, sure, we could always define a DSL to be that. I think that’s setting the bar a bit too low. There has to be cutoff point. Yours is definitely in a different place than mine and that’s okay :-)

simongray 2021-01-04T22:00:11.457700Z

Obviously, DSLs are usually meant to do very specific things, so I’m not saying that the purpose of the DSL can’t be simple, but if its grammar is incredibly basic too… then the number of items in the list will definitely need to be of a different magnitude entirely. I’m not sure it would be fit for the purpose I had for it any longer (documenting DSLs in Clojure and tools for making them).

simongray 2021-01-04T22:02:11.458100Z

That said, I am definitely considering adding a separate section for data-oriented configuration and alike, since it’s so common in Clojure.

borkdude 2021-01-04T22:03:11.458300Z

So is deps.edn a DSL: the machinery behind it is certainly not trivial, but the data format is "just EDN". Same with writing Docker semantics in JSON. It's very blurry.

simongray 2021-01-04T22:03:53.458500Z

It’s definitely blurry. I already have a disclaimer in the list about that > In either case, a supposed DSL could just as easily be considered a creative use of existing language features or a particularly well-designed API.

borkdude 2021-01-04T22:04:14.458700Z

Thanks for the interesting discussion :)

simongray 2021-01-04T22:04:35.458900Z

You too. 😉 thanks for making cool stuff.

simongray 2021-01-04T22:47:04.459100Z

@ikitommi @borkdude here’s where I ended up putting it https://github.com/simongray/clojure-dsl-resources#data-oriented-configuration