Fork me on GitHub
#clojure
<
2021-01-22
>
solf08:01:33

It seems awesome, but there's too few info to really comment on it

baptiste-from-paris08:01:45

we are working on it, we’ll make a tweet ~1 a week to keep you update

kosengan10:01:35

Cool 🙂 This seems next in the line of joker-lang. But please give a cool name 😎

cgrand19:01:21

Unless forbidden to, we’ll go for a boring name like ClojureDart.

👍 1
didibus22:01:55

As I understand, this is compiled to Dart correct? Not an interpreter?

phronmophobic22:01:20

yea, I think I read a tweet that it produces Dart source code

didibus00:01:50

Oh cool, so it compiles to Dart source code, interesting

didibus00:01:40

Wonder how that will play with REPLs and other dynamic use like "eval" and support for Vars

cgrand13:01:37

It depends. When you run in dev mode, you are in the dart vm and you can redef and eval. The compiler can only run in this mode. When you run your cljd code as a native executable you can’t eval or redef.

👍 2
didibus23:01:21

That seems good then, similar to native Clojure with GraalVM it would seem.

xceno18:01:52

Is there a way to pretty print transients in the repl, so I see the actual content and not just the type name?

noisesmith18:01:47

@rob703 I'm realizing that the reason I don't have an answer to this is that I've always taken transients as a hack (14% or so speed increase), so as soon as I need to debug something I stop using them

noisesmith18:01:59

someone else might have a better answer

xceno18:01:24

that's exactly my problem now. I have an infinite loop i need to debug

noisesmith18:01:55

might be easiest to call persistent! while debugging - that makes the next transient op blow up, but it prints clearly

noisesmith18:01:42

(of course you can create a new transient to use in the place of the old one too)

xceno18:01:02

That's what I did for a while but I find it highly annoying when everything blows up while debugging I'd be ok with "copy-transient-and-print-it"

noisesmith18:01:04

(unless you are bashing in place, which means you are using transients wrong and that's the likely cause of your bug)

noisesmith18:01:21

(defn debug-transient [t message] (let [p (persistent! t)] {prn message p) (transient p)) - something like that should be safe, it gives you a new transient back to use with the same contents

noisesmith18:01:09

the only reason you couldn't use that is if you are using the transient but not using the return value of conj! / assoc! etc., which, in this case, is the probably source of your bug

xceno18:01:48

Hm fair enough, if the sort order remains the same that'll be good enough for now. I made sure to use the return value, so that's fine. The real problem is that I needed to translate a really hardcore imperative algorithm into clojure/fp and it's gotten real ugly (who would have thought)

noisesmith18:01:51

but more generally, I'd be suspicious of using transients for anything complex enough to need debugging - use normal collections then rewrite with transients when the tests pass

👍 1
xceno18:01:16

Yes that's what I'll probably do now

noisesmith18:01:27

if you think transients will help you do an imperative algorithm, you're already on the wrong track

xceno18:01:11

I've chosen them only for speed reasons, instead of an atom... I should have chosen the atom though it seems

noisesmith18:01:38

the idea that a transient could replace an atom is already an error

noisesmith18:01:45

they have the same api as normal collections, just different function names

noisesmith18:01:56

they accidentally let you update in place, but that's not a defined behavior, it's just incidental - they are allowed to do so, and never promise to do so

xceno18:01:42

Yes I found out afterwards and rewritten my code accordingly. But that's the thing. When I want to speed up code that is using an atom right now, I have to rewrite it anyway in order to use transients properly. So I figured I might as well go all in and write my algorithm only with transients. So yah, now I'm here, trying to debug things 🙂

xceno18:01:52

but thank you, I'll try your debug snippet

noisesmith18:01:23

@rob703 the thing that's meant to be an atom but faster is volatile! - but that only works in single threaded code

noisesmith18:01:10

which means the effective way to use both is to use normal collections and container types first, get your code working, and if it's still too slow swap in a volatile! or transient if it's apropriate

xceno18:01:50

I see, thank you. I'll keep that in mind as a hard earned lesson. I think my main problem was half-assing the translation from the oop/imperative to the clojure version. So I gotta clean that up now

kwladyka19:01:51

Edit: moved to #ring

borkdude19:01:54

@kwladyka I'm not sure if this question belongs in #clojure - also please don't flood the channel with JSON

borkdude19:01:49

I mean, you can make this into a gist perhaps.

kwladyka19:01:57

ok I will ask on #ring then

oliver21:01:45

Hi! I want to build specs from a sequence of maps. Of course, spec/def being a macro, I cannot just map over the sequence. I could achieve it by using a macro myself, but I was wondering if it can be done with functions only. There is spec/def-impl, which is a function, but its docstring discourages its use… any ideas? (I'll totally take no for an answer.)

John Conti23:01:23

(defmacro functionize [macro]
  `(fn [& args#] (eval (cons '~macro args#))))

(let [a [true]] (apply (functionize and) a))
=> true
https://stackoverflow.com/questions/9273333/in-clojure-how-to-apply-a-macro-to-a-list has always struck me as the least tortured way to deal with macros, by simply turning them into functions.

🙏 1
oliver18:01:28

Hi! Sorry, I only just noticed your message (I'm not that used to navigating slack). thats actually a great little piece of code, thank you that I will definitely add to my vault! (I'll not be able to use it for my immediate use case since eval is not available in ClojureScript afaik) Cheers!

John Conti21:01:02

Glad I could offer something. I had forgotten about eval in Clojurescript, and I haven’t used it since the self-hosted compiler project started. So I had to ask duck duck go the state of play, and came across https://gist.github.com/mfikes/66a120e18b75b6f4a3ecd0db8a976d84. I know nothing about the viability of this implementation of eval. But it is a very exciting step in that compiler’s development that it can provide it. But other than enthusiasm I have no direct experience with it. Though functionalizing a macro seems like a good fit for it.

simongray21:01:38

Try malli instead

oliver21:01:13

Thanks, taking a look at it right now…

borkdude21:01:56

@services yeah, there is no way doing that without a macro, or using the discouraged impl

hiredman21:01:18

technically it is possible, the most straightforward way being using eval

borkdude21:01:35

yeah, macro or eval, kind of the same thing

hiredman21:01:40

in theory spec2 is supposed to make that sort of thing easier

alexmiller21:01:58

s/register can be used for this in spec 2

hiredman21:01:26

but what I would do (and do all the time), is just write some code to generate the s/def forms, run that code in the repl, and then copy and paste those forms back in to your code

hiredman21:01:35

(assuming the maps are fairly static)

simongray21:01:39

It's a data-oriented Spec replacement, basically, made by metosin who also made spec-tools: https://github.com/metosin/malli

Grant Isom21:01:27

Got a weird question: I am trying to format a request with Cheshire to have a key "\$oid" , but it only seems possible to get \\$oid. Is there a way to escape $ solely?

hiredman21:01:11

you are likely being confused by printing at the repl

Grant Isom21:01:53

When I actually send the request it still is \\$oid

hiredman21:01:03

how do you know?

noisesmith21:01:38

there is no clojure syntax to escape $ in a string, because it's not special

noisesmith21:01:05

\ prints as \\ unless you are printing for display

hiredman21:01:51

user=> "\\$oid"
"\\$oid"
user=> (println "\\$oid")
\$oid

hiredman21:01:03

user=> (seq "\\$oid")
(\\ \$ \o \i \d)
user=>

Grant Isom21:01:53

When I actually made the request, the key for the JSON object was still \\$oid

hiredman21:01:24

do you mean the it was serialized in the json that way?

hiredman21:01:38

because the same escaping happens in json

noisesmith21:01:54

the string that prints normally (with println) as "\\$oid" would print for reading (with prn) as "\\\\$oid"

Grant Isom21:01:34

I guess I am not trying to escape the dollar as I am trying to escape the slash. I need it to be received \$ because in another env I need to escape the dollar.

noisesmith21:01:15

@grant.isom no clojure string will ever prn as "\" undoubled, and the repl uses prn

oliver21:01:32

@hiredman, @borkdude Thanks to both of you! 1. I'm on ClojureScript, so no eval for me 😔 2. The Sequence is not static, since it is supposed to be edited by my customer who wants to compile the app on his own and generate different versions (we'll see how that works out). Altogether this is not super important, since I already have implmented a working macro-solution… just thought I might simplify it and gain a better understanding of spec @simongray Malli sure does look like an interesting choice fo my use case. One of my goals is to match an existing Swagger2 Schema… which apparently Malli schemas can be transformed into…

borkdude21:01:58

@services swagger-like JSON API things is really where Malli probably shines

borkdude21:01:59

as malli also supports coercions out of the box, and spec doesn't

borkdude21:01:09

and for other reasons maybe too

Grant Isom21:01:04

Okay found out cheshire was escaping my escapes haha

oliver21:01:35

@simongray, @borkdude Looks like the Malli Readme will be my bed-time reading for tonight…thanks! For the record: what I'm trying to do is to declare the constraints on my data in one place and then impose them on my API-request as well as on the input fields in my form (e.g. max-length attributes and field validation)

simongray21:01:23

I haven't used Malli myself, only spec, but it seems like it would fit your use case.