Fork me on GitHub
#beginners
<
2017-11-02
>
max03:11:36

language question!

max03:11:53

In a (cond) statement, I can evaluate a bunch of tests, and the first one to evaluate true will return the value of its corresponding expression

max03:11:59

then, there is :else

max03:11:02

My question is: Does :else somehow evaluate to true? How does this work? Is the keyword :else just used by convention?

donaldball03:11:35

It’s just convention. Any truthy value will work.

max03:11:17

Yeah, I changed it to :test in my code and it still worked

max03:11:43

I'm not sure in what way a keyword is truthy though. If I try (true? :test), it returns false

donaldball03:11:36

true? is a specific test for the true boolean value. Anything that passes boolean is truthy, namely any value that is neither nil nor false.

max03:11:41

(boolean :else) returns true. I get it now. Thanks!

max03:11:33

:spock-hand:

noisesmith04:11:15

boolean accepts some values as false that if (and therefore cond) does not btw

+user=> (if (Boolean. "FALSE") :yes :no)
:yes
+user=> (if (boolean (Boolean. "FALSE")) :yes :no)
:no
+user=> (cond nil 0 false 1 (boolean (Boolean. "FALSE")) 2 (Boolean. "FALSE") 3 true 4)
3

noisesmith04:11:38

but nobody should be making new instances of Boolean anyway, so it's a serious corner case

Arno Rossouw13:11:44

Can i do everything in typedclojure that the mainstream clojure can do?

seancorfield15:11:20

@arno Typed Clojure is "just" an annotation system and analyzer for Clojure -- so what you're writing is still Clojure.

rcustodio15:11:30

hi… i need to check if the email exists on database, is there anyway of doing that using clojure.spec?

dpsutton16:11:26

that really sounds like application logic to me

dpsutton16:11:25

and putting network traffic into "meta" code is a recipe for disaster

rcustodio16:11:58

how to make this work?

(spec/def ::geoloc (spec/keys :req-un [::latitude ::longitude]))
(spec/def ::address (spec/keys :req-un [::type ::country ::postal ::state
                                                  ::region ::street ::number ::geoloc]
                                         :opt-un [::adjunct ::reference]))
(spec/def ::billing_address (spec/keys :req-un [::type ::country ::postal ::state
                                                          ::region ::street ::number ::geoloc]
                                                 :opt-un [::adjunct :reference]))
(spec/def ::document (spec/keys :req-un [::number ::type]))
(spec/def ::phone (spec/keys :req-un [::country-code ::area-code ::number]
                                       :opt-un [::extension]))
(spec/def ::company (spec/keys :req-un [::type ::document ::corporate_name ::contry
                                                  ::billing_address ::address ::email ::phone]
                                         :opt-un [::fantasy_name ::brand_name ::state_tax_id ::city_tax_id]))
throws
CompilerException java.lang.AssertionError: Assert failed: all keys must be namespace-qualified keywords
(every? (fn* [p1__1857#] (c/and (keyword? p1__1857#) (namespace p1__1857#))) (concat req-keys req-un-specs opt opt-un)), compiling:(atrium/company/validator.clj:14:29) 
~

noisesmith16:11:21

what is :opt-un and why isn't it namespaced?

rcustodio16:11:46

it’s optional values

Hendrik Poernama16:11:46

opt-un is optional, strip namespace

noisesmith16:11:23

what about :reference (other places it's ::reference)

rcustodio16:11:34

oh havent saw that

Hendrik Poernama16:11:43

yeah, that's the problem, nice eyes

rcustodio16:11:12

yes, thanks, im programmimg since this morning, eyes are becoming slower

noisesmith16:11:13

the line number would have made it easier if we saw it, heh

noisesmith16:11:34

I assume that spec/def call was on line 14 of the original

rcustodio16:11:08

it was, and i was search btw

::type ::country ::postal ::state

noisesmith16:11:39

a good editor can take that validator.clj:14:29 and jump straight to the error (if the line/column was generated properly at least)

rcustodio16:11:02

Hmm, I see, I use emacs

rcustodio16:11:18

But I use mac terminal for repl

danm16:11:20

If you use emacs, why are you not using Cider? I thought that did all the repl integration stuff

noisesmith16:11:17

@carr0t it does, it also adds some complexity and brittleness and not everyone rates the tradeoffs the same way

noisesmith16:11:57

I don't use fireplace, I just use vim, for the same reason I run debian stable - things break enough just from me being dumb, I don't need to add unstable tools on top of that to drive myself crazy 😄

rcustodio16:11:59

I will try it later, but I like the pure emacs

rcustodio16:11:45

@noisesmith lol, I’m dumb as well, thats why I prefer pure emacs

noisesmith16:11:49

I like the extra confidence that if things go wrong I know it's not tooling weirdness (though I hear cider and related tools are much more reliable than they once were)

rcustodio16:11:54

@noisesmith is there anyway to use spec validation with db query (mongo)? check if something exists

ajs16:11:50

@noisesmith without fireplace, what is your workflow like with vim? Quite curious, as I'm thinking of switching to vim myself.

noisesmith16:11:19

I use load-file and require with a reload argument to hot load code

noisesmith16:11:08

(load-file "/home/justin/clojure/foo/src/foo/bar.clj") (works even with libs) (require 'foo.bar :reload) (only works with things loadedfrom the current project)

noisesmith16:11:26

also (load-file "/tmp/experiment.clj") or similar

noisesmith16:11:13

I also have a library that stores the data I am looking at in the repl into a file, so that it can be transparently loaded in a new repl, or in a unit test https://github.com/noisesmith/poirot

noisesmith16:11:04

I use clojure.repl/doc clojure.repl/apropos and clojure.repl/source to figure out how to use other people's code (or go to github and browse as a last resort)

noisesmith16:11:23

though I find if I have to look up docs I probably want javadoc anyway a decent percentage of the time

ajs16:11:58

Interesting. So you just run a repl from terminal, like lein repl?

ajs16:11:33

And you just use vim for the text editing only?

noisesmith16:11:23

technically I have fireplace installed, but I'm not using the cider plugin it requires for advanced stuff and I never use its features

ajs16:11:41

I like that, keeping it minimal. I assume you just use vanilla vim, or neovim? And what vim tools, just vim-sexp? Any others?

ajs16:11:58

Vim Clojure-static?

noisesmith16:11:25

vim-sensible, vim-sexp, vim-clojure-static, gundo are the ones I use for clojure editing

ajs16:11:21

I may hit you up later for advice as I experiment. I prefer vim editing, but evil mode only goes so far.

noisesmith16:11:13

yup my path was vim (for a few months) emacs (for decades) wrist pain, then evil mode, then vim again

noisesmith16:11:31

not chording plus a split keyboard completely eliminated RSI problems btw

ajs16:11:26

Aren't there still chords for sexp?

noisesmith16:11:44

not that I ever need to use

noisesmith16:11:08

I either remap to a leader plus individual keys, or ignore the feature - eg. I remapped all my window / buffer management to single keys

noisesmith16:11:35

I could do the same thing in emacs, but vim is closer to the target of not chording from the get-go

noisesmith16:11:02

I mean - I still use the shift key, and ever so rarely the control key of course

noisesmith16:11:11

but it's not constant like it was even with evil mode for me

ajs16:11:56

My problem with evil mode is you are still in emacs and need emacs bindings for some tools. And evil was per buffer and diff buffers would be in diff evil modes

chris20:11:16

fwiw spacemacs has been working on this stuff for awhile

chris20:11:26

I'm happy with how it's working now

mseddon21:11:12

\o/ clojure.pprint/cl-format has made me happy 🙂 - is it ANSI compliant or are there any documented gotchas?

mseddon21:11:21

also, why is there a defn- but not a def-?

noisesmith21:11:43

I can only speculate, but my assumption has been that def should be using immutable data anyway, and if you really want data hiding you should use let and not def

noisesmith21:11:53

maybe someone has a better answer

chris21:11:58

^^^ afaik this is the correct answer

mseddon21:11:24

good enough. 🙂

noisesmith21:11:32

an idiomatic thing is passing the value to the things that need to use it explicitly, rather than using access control around a (namespaced) global value

mseddon21:11:29

I'm definitely definitely enjoying clojure. Taking my time to reduce code results in the smallest, clearest lisp I've used

noisesmith21:11:33

it's very opinionated, but its opinions are usually good choices in my experience

mseddon21:11:51

opinionated seems to beat minimalist and backward compatible so far 🙂

mseddon21:11:31

and the opinions, once I've grokked them, are usually good. I don't know what it'll be like to e.g. use opengl or something very heavily stateful yet, but I'm trying to ignore that problem for now and stick with what's natural

noisesmith21:11:00

opengl is pretty far from clojure's sweet spot too, idiomatic clojure would create way too much garbage I bet, and make the API annoying to use without adding benefit - unless we are talking about something much higher level that uses Opengl, rather than wrapping it for other clojure users

noisesmith21:11:05

but that's just speculation...

mseddon21:11:35

that's my current assumption. haskell is similar. opengl code winds up looking like any other imperative programming language

noisesmith21:11:02

except probably being clumsier (I bet the clojure version would be even clumsier than the haskell version actually)

mseddon21:11:44

hehe, that remains to be seen. that said, clojure could make a very acceptable high level interface over java providing a more retained mode scenegraph

mseddon21:11:05

the garbage would be tiny tweaks rather than megabytes of vertex arrays

noisesmith21:11:17

but! clojure has this great ability to integrate with java in both directions - so you can easily have java classes that interact with opengl and an AI that controls it in clojure all in one project with seamless interaction in both directions

mseddon21:11:30

😄 that ^

mseddon21:11:12

my day job (like so many others) is pulling chunks of data out of persistent storage, munging it and stuffing it somewhere else, and for that, it seems pretty good (once I've grasped the core)

noisesmith21:11:32

yeah, clojure is best in class for ETL as far as I know

phronmophobic21:11:42

i’ve been using clojure with opengl and been having a lot of fun with it

phronmophobic21:11:54

although i’ve been accessing opengl through jna

mseddon21:11:05

really? that's promising 🙂

phronmophobic21:11:17

i’d be happy to share my code, but it’s a kind of a mess

mseddon21:11:23

i did a bunch of gl in CL and it was damn performant and fun

noisesmith21:11:44

when I first learned clojure I thought I had become an ETL genius, but no, not at all, I just learned a language that is very good at that domain haha

mseddon21:11:09

@smith.adriane my code is also a mess, but happy to swap ideas, i love playing with that stuff

phronmophobic21:11:33

i’m very interested in finding good resources for the best way to design for that

mseddon21:11:36

@noisesmith haha, i've found a lot of other solutions to be cognitive overload

phronmophobic21:11:07

@mseddon do you have any links for how things were used from CL?

mseddon21:11:31

in CL it's kinda different, really it's no more exciting than standard C stuff

mseddon21:11:41

we're mutable and hairy

mseddon21:11:04

bonus points for DSLs for GLSL (all homebrew)- and multimethods which are really fast in sbcl

mseddon21:11:53

but actually someone here earlier today who turned up is a professional games engine developer in C++, was discussing John Carmack porting wolfenstein to haskell

mseddon21:11:14

tim sweeny (of Epic/Unreal) was also publishing about FP in gamedev

mseddon21:11:34

I will try and find you some CL resources- it's been quite a few years since I was embedded in there

phronmophobic21:11:09

my main use case is more for creating UI rather than for a game engine

phronmophobic21:11:20

which clojurescript is being used for all the time

mseddon21:11:23

oh! I have some code you might like

noisesmith21:11:36

there's that clojure-clr port to run in a windows game engine, but if you look at what they did to get it to run with any acceptable performance inside the render code it's kind of insane - they made their own custom byte code emitting dsl that looks just like clojure but only does things they can promise are fast enough

mseddon21:11:15

may be boring, slightly random, also scala.js 🙂

phronmophobic21:11:38

i’ve actually been really surprised at how responsive the UI’s I’ve been making are even with my extremely naively implemented code

mseddon21:11:43

but optimized blitter stuff, I have other things up (polymorph) that contain layout managers (pack/grid) ala gtk/qt

mseddon21:11:57

webgl is incredibly fast, compared to dom

mseddon21:11:24

the problem i found was text input on mobile, and handling international text performantly on mobile (though that has recently just got fast enough to not matter)

phronmophobic21:11:45

the UI’s i’m creating are running on my laptop via opengl

phronmophobic21:11:10

which probably helps that desktops have access to lots more cpu

mseddon21:11:30

yeah, desktop does help- i actually have some probably unpublished truetype font parsers for that, too

phronmophobic21:11:42

ok, i’ve been using freetype

mseddon21:11:43

on ipad 3 it took like 1second to parse a ttf

mseddon21:11:02

ah- yeah, not in a browser, right?

mseddon21:11:14

yea, the sane spot 🙂

phronmophobic21:11:46

I can use socket connections, talk to the file system, easy multi threading

mseddon21:11:58

you can block. the luxury 🙂

phronmophobic21:11:33

pmap, promise, thread, future

mseddon21:11:49

tbf the repo i linked may not be so useful. it's about blitting quads as fast as is practical on a browser on a mobile

mseddon21:11:28

but it's WebGL 1, so OpenGL/ES2- there are better ways on a desktop, and frankly, i don't think you really pay for it doing it another way

phronmophobic21:11:52

cool, i’ll check it out!

mseddon21:11:38

can't remember! 🙂

mseddon21:11:33

if it does, i know you need to add the texture derivative (dFdx, dFdy) extension to it to be better.

mseddon21:11:25

@noisesmith what is the status of clojureCLR?

mseddon21:11:52

i've done some professional unity work in the past (version 3) in c# and it was a bloody nightmare

mseddon21:11:33

specifically, async/await sucks, and clojure.async is brilliant

seancorfield21:11:28

According to the commit list on the ClojureCLR repo, it's currently tracking Clojure (JVM) as of March 14th this year.

seancorfield21:11:44

Which is 1.9 Alpha 15

mseddon21:11:51

huh, that's further than i would expect

rcustodio21:11:25

For service I think clojure must be awesome, but is it for client?

mseddon21:11:48

that said, the last time i started out with clojure, it was in 2009 and the CLR implementation was DOA

rcustodio21:11:17

The slow start doesn’t make it bad?

mseddon21:11:34

@rcustodio clojure isn't slow to start natively on desktop

mseddon21:11:43

lein is slow to start though 🙂

mseddon21:11:11

aot uberjar will fix it, provided your game engine runs fast enough once it's up and running, i would say

rcustodio21:11:20

Oh, I see, so it’s good for client and service

mseddon21:11:35

well. what is your minimum spec?

mseddon21:11:41

raspberry pi is going to suuuck

rcustodio21:11:50

@seancorfield in this case aot is good?

mseddon21:11:00

but i've made swing apps that boot instantly on an i5

rcustodio21:11:10

Just asking, I’m interested in game dev but never did it

seancorfield22:11:20

AOT could reduce your startup time so it could improve your application's time to launch; I would avoid it while developing and then try a fully AOT-compiled uberjar for "production", and compare startup times.

athomasoriginal22:11:29

Is it possible to destructure a #object[HTMLDivElement] in CLJS? Right now I have this

(let [width  (.-offsetWidth Element)
        height (.-offsetHeight  Element)] ;; ...
and I was thinking it would be nice to be able to do something like this:
(let [width :offsetWidth height :offsetHeight] Element] ;;...)