Fork me on GitHub
#beginners
<
2018-03-05
>
jonathan00:03:23

thanks for the help guys, the space issue was a Cursive configuration option related to pretty printing (useful for data structures)

derpocious02:03:42

hey all, I'm getting an error trying to load a local edn file

derpocious02:03:04

this is the file, creds.edn

derpocious02:03:08

{:consumer_key        "asdadasdasd"
 :consumer_secret     "asdasdasdasd"
 :access_token        "asdasda-asdasdasdasd"
 :access_token_secret "asdasd"}

derpocious02:03:54

and some code to load it:

(ns cool-beans.core
  (:require-macros [cljs.core.async.macros :refer [go]])
  (:require [cljs-lambda.util :as lambda]
            [cljs-lambda.context :as ctx]
            [cljs.nodejs :as nodejs]
            [cljs-lambda.macros :refer-macros [deflambda]]
            [cljs.core.async :refer [put! chan <!]]))

(def credsMap
  (-> (nodejs/require "fs")
      (.readFileSync "static/creds.edn" "UTF-8")
      read-string))

derpocious02:03:21

using clojurescript 1.10.64

derpocious02:03:41

but I get the error: module initialization error: TypeError

mfikes02:03:33

@derpocious It would be interesting to know if that is a regression in 1.10.64 (a beta release) relative to 1.9.946 (the current version)

derpocious02:03:22

that's the exact syntax to load an edn file in the starter project made from lein cnew cljs-lambda which uses cljs 1.8.51

derpocious02:03:46

I upgraded my project, but I'm not sure if the syntax changed or I'm just doing something wrong

derpocious02:03:06

Seems weird to me though that you would use the nodejs version of require for edn files

mfikes02:03:08

Where does read-string come from?

derpocious02:03:10

oh maybe I am just missing the require for it

derpocious02:03:12

[cljs.reader :refer [read-string]]

mfikes02:03:03

@derpocious FWIW, if I compile

(ns cool
  (:require
   [cljs.nodejs :as nodejs]
   [cljs.reader :refer [read-string]]))

(def credsMap
  (-> (nodejs/require "fs")
      (.readFileSync "static/creds.edn" "UTF-8")
      read-string))

(prn credsMap)
with 1.10.64 and run it in Node, it prints out
{:consumer_key "asdadasdasd", :consumer_secret "asdasdasdasd", :access_token "asdasda-asdasdasdasd", :access_token_secret "asdasd"}

mfikes02:03:26

Since you are using 1.10.64, you can use cljs.main to test that it works by doing

clojure -Srepro -m cljs.main -re node cool.cljs
with deps.edn containing
{:deps {org.clojure/clojurescript {:mvn/version "1.10.64"}}}

mfikes02:03:08

But, if you want to use a 1.10 beta, 1.10.126 is available now

derpocious02:03:39

mine says 1.10.64

derpocious02:03:58

but I just used lein ancient upgrade :check-clojure to upgrade

derpocious02:03:13

is there a way to specify a version?

mfikes02:03:48

If you are using lein, the ClojureScript version being used is in project.clj

derpocious02:03:19

can I just change it in project.clj, do lein deps, and then everything should work?

mfikes02:03:49

Yes. You don't even need to do lein deps

derpocious02:03:49

don't I need to change the clojure version with it?

derpocious02:03:06

or 1.9.0 should be fine

mfikes02:03:55

Yes, the ClojureScript 1.10 betas run fine with Clojure 1.9.0

derpocious02:03:14

thanks. but suppose I have this code and want to extract the map into a separate edn file

derpocious02:03:28

(def Twitter
      (new twit
           #js {:consumer_key        "sfgs"
                :consumer_secret     "sdfgdsg"
                :access_token        "sdfg-zsdfgsdfg"
                :access_token_secret "sfgsdfgsdfg"})))

derpocious02:03:01

an am getting error that it's expecting map, but when I try to use the defined map it give me an error

mfikes02:03:33

@derpocious The read-string call is returning a persistent map. In your Twitter example, that is a JavaScript object. (Note the #js.) You can convert your persistent map to a JavaScript object using clj->js.

mfikes02:03:41

In other words, you likely want to pass (clj->js credsMap)

mfikes02:03:13

Backing up a little, I'm assuming you are doing

(def Twitter
         (new twit credsMap))
and instead you likely need
(def Twitter
        (new twit (clj->js credsMap)))
based on your example above

derpocious02:03:07

wow, excellent 🙂

derpocious02:03:23

is that all one thing, cljs->js

derpocious02:03:28

like is that one macro?

mfikes02:03:52

It is just a function with a name clj->js

mfikes02:03:07

(The arrow is part of the name)

mfikes02:03:49

cljs.user=> (clj->js {:foo 1})
#js {:foo 1}

derpocious02:03:13

interesting, but why do I not have to require it?

mfikes02:03:15

cljs.user=> (js->clj #js {:foo 1})
{"foo" 1}

mfikes02:03:32

It is cljs.core/clj->js; since it is in core, there is no need to require it, like map, filter, etc.

derpocious02:03:18

well thanks a lot for all the knowledge! I'm going to continue on until I hit another roadblock. 🙂

nakiya06:03:49

I have a function I use to solve n-puzzle using A*. Though this works for 3x3 puzzles fast enough, it takes hell of a long time to solve a random 4x4 puzzle (I have run the algorithm for a random 4x4 puzzle for two hours and still no result). So I want to profile the code. I want memory usage of each maps/sets/lists being used and I want to get timings for functions.

schmee10:03:55

you can use jvisualvm for this. it’s not a Clojure-sepcific tool, but it comes install by default with Java and is a good starting point imo

nakiya06:03:22

What tool could I use? If it’s non-intrusive (I don’t have to do any code change), better

nakiya06:03:28

I am using clojure

serepasf09:03:55

Hello guys. Do you have to suggest me any tutorial or book for beginner? I am coming from Python 😁

sundarj10:03:57

Since you already know programming, you should pick up Programming Clojure: https://pragprog.com/book/shcloj3/programming-clojure-third-edition

sundarj10:03:18

other beginner books which are good: Clojure for the Brave and True, and Living Clojure

sundarj10:03:12

welcome to Clojure! 🙂

orestis11:03:03

I am also coming from the Python world — I attempted to create a 15' tutorial here: https://orestis.gr/your-first-clojure-code/

orestis11:03:33

It’s not finished or complete, but it aims to get you started really gently.

Russ Olsen15:03:04

OK, perhaps I can be forgiven for plugging my own book... Getting Clojure, currently in early release, is also aimed at beginners. If you want you can check out some sample chapters over at http://bit.ly/gettingclojure But obviously I'm biased.

jumar09:03:09

Although I didn't read Russ' book yet, it looks very interesting and I'm looking forward to reading it. It also includes some latest stuff like Spec. I don't consider myself to be a Clojure beginner anymore but I believe every Clojure novice can get tremendous value from it.

cgrand13:03:33

@dbsgtk jump to #unrepl

joshkh13:03:10

does anyone have a safe and lazy way of serving their js files from node_modules (ex: jquery)? do you use lein to move individual files to public directories? or do you set up a separate route and serve small parts of the node_modules directory? the latter seems to be the recommended method but it feels wrong to serve files from outside the public directory.

sundarj13:03:32

you could make symlinks?

joshkh14:03:28

oh hey, there's an idea! thanks

sundarj14:03:40

no worries 🙂

timo16:03:25

Hi there, how do you manipulate the app-db in re-frame from the repl?

joelsanchez16:03:00

by dispatching events 🙂

timo16:03:04

alright thanks! that's what I was thinking of but did hope to get something more like ... direct

timo16:03:27

I like it

Scot16:03:37

You can (for dev purposes) create a event subscription pair to modify the DB however you wish

(reg-event-db
  :reset-db! 
  (fn [_ [_ new-db]] new-db)) 
(reg-sub :db (fn [db _] db)) 
(dispatch [:reset-db! (my-update-fn @(subscribe [:db])))

Amelia16:03:09

Is there a channel for beginners who are totally new to programming and learning Clojure as a first language? I’ve been to two introductory workshops with one-on-one coaching, but this channel’s content still seems very advanced to me. It’s pretty intimidating, there’s no way I’d feel comfortable posting my much more basic questions here.

chris16:03:10

tbh you should just ask here

chris16:03:20

you're not going to be clogging up the channel or anything

Scot16:03:59

People in this channel tend to be pretty patient and understanding. While there are some more intermediate questions in this chan, I'm sure everyone is happy to answer questions at any level. ask away when you're ready! 🙂

val_waeselynck16:03:09

@amelia ask away, if anything it will make us better teachers

Amelia16:03:02

I appreciate that, but as a complete newbie I think I’d just feel too self-conscious in this space. I asked the question in part to highlight the issue - I’m speaking up, but you should consider that not everyone will.

bronsa16:03:57

there’s tons of complete newbies here — this is exactly what this channel is for. A channel specifically for people new to programming doesn’t exist in this slack (yet? :) )

bronsa16:03:37

a #programming-beginners channel could be a good idea but there’s the problem that there’s 3.7k people here and 0 in a non existent channel

Scot16:03:47

I just made one

Scot16:03:57

everyone here should join in

Scot16:03:13

let's make clojurians as accessible as we can! 🙂

bronsa16:03:32

@amelia in the meantime you should really feel free to ask here tho

val_waeselynck16:03:53

I was gonna say it's not a good idea, but hell I don't see any downside to giving it a try 🙂

Scot16:03:48

worst case scenario it is a smaller channel where some or most questions escalate to here, but it is at least a safe space to test the waters

jonathan16:03:36

https://www.maria.cloud looks like a great intro to programming using Clojure

Amelia16:03:45

Thank you! 😁 I’ll contribute as much as I can, probably not hard since I spent hours yesterday just asking myself “Why won’t this work” over and over about something extremely simple

sundarj16:03:05

you would be surprised how often that happens to experienced programmers too 😛

jonathan17:03:19

You might be surprised that you’re likely a better programmer already than some professionals who have been doing this for 10-20 years!

Amelia17:03:27

I doubt that VERY much, but I appreciate that this is apparently within reach!

jonathan17:03:02

No it’s true. I have interviewed some with over 20 years experience in a single programming language that cannot even code something simple like: Create a list of numbers.

jonathan17:03:50

It's a strange market. Programming itself is easy, e.g. write a function that given some input returns some output. Yet no one has really created a blueprint of how to successfully build a real application. Most of us come to Clojure after years of pain with other programming languages.

sundarj17:03:45

we are a very young industry still, and it shows 🙂

Amelia17:03:54

I’ve gone to introductory events for a number of languages, and I work in a tech startup with developers who’ve been kind enough to walk me through basic principles, but at a point now where I just need to focus on one and build up a working knowledge. Clojure is my favourite so far, and the inclusiveness of the community is a real plus (and the reason I felt comfortable asking about an alternative channel).

jonathan17:03:39

The only downside is the market for Clojure jobs (and functional programming languages) is still really small. The plus side is that you will have a skillset that few developers have.

Amelia17:03:33

I actually just want to be able to build things for myself - I’m a bit entrepreneurial, and being unable to code what I can imagine is holding me back. I like the simplicity of Clojure, being able to code what I can imagine actually feels near-future possible.

sundarj17:03:19

@amelia building things for yourself is a lot of fun 🙂 and it's a great way to learn

Amelia17:03:35

I have the perfect beginner project in mind, just need to get a bit more comfortable with basic stuff (like defn!) then I’ll get started.

sundarj17:03:50

sounds good!

Amelia16:03:30

I took a look at Maria yesterday but after two introductory workshops it covers a fair amount I’ve looked at there

liamd16:03:13

hey so i'm having an issue importing a library

liamd16:03:33

here's the relevant piece of code in my project

(ns clogue.display.ascii-window
    (:require [lantera.screen :as s]))

liamd16:03:59

here's the error when i run

Exception in thread "main" java.io.FileNotFoundException: Could not locate lantera/screen__init.class or lantera/screen.clj on classpath., compiling:(clogue/display/ascii_window.clj:1:1)
	at clojure.lang.Compiler.load(Compiler.java:7391)
	at clojure.lang.RT.loadResourceScript(RT.java:372)
	at clojure.lang.RT.loadResourceScript(RT.java:363)
	at clojure.lang.RT.load(RT.java:453)
	at clojure.lang.RT.load(RT.java:419)
...

liamd16:03:24

but:

❰liamdyer❙~/mydev/clogue❱✔≻ jar tvf ~/.m2/repository/clojure-lanterna/clojure-lanterna/0.9.7/clojure-lanterna-0.9.7.jar
   116 Thu Nov 24 12:17:02 CST 2016 META-INF/MANIFEST.MF
  2796 Thu Nov 24 12:17:02 CST 2016 META-INF/maven/clojure-lanterna/clojure-lanterna/pom.xml
   636 Thu Nov 24 12:17:02 CST 2016 META-INF/leiningen/clojure-lanterna/clojure-lanterna/project.clj
   636 Thu Nov 24 12:17:02 CST 2016 project.clj
   377 Thu Nov 24 12:17:02 CST 2016 META-INF/leiningen/clojure-lanterna/clojure-lanterna/README.markdown
     0 Thu Nov 24 12:17:00 CST 2016 META-INF/
     0 Thu Nov 24 12:17:00 CST 2016 META-INF/maven/
     0 Thu Nov 24 12:17:00 CST 2016 META-INF/maven/clojure-lanterna/
     0 Thu Nov 24 12:17:00 CST 2016 META-INF/maven/clojure-lanterna/clojure-lanterna/
   108 Thu Nov 24 12:17:00 CST 2016 META-INF/maven/clojure-lanterna/clojure-lanterna/pom.properties
     0 Thu Nov 24 12:14:40 CST 2016 lanterna/
   997 Sat Dec 12 13:17:56 CST 2015 lanterna/common.clj
  3275 Sat Dec 12 13:17:56 CST 2015 lanterna/constants.clj
  9455 Thu Nov 24 12:14:40 CST 2016 lanterna/screen.clj
  8729 Sat Dec 12 13:22:20 CST 2015 lanterna/terminal.clj
     0 Sat Dec 12 13:17:56 CST 2015 README.markdown

liamd16:03:13

oh goddammit

liamd16:03:18

of course

liamd16:03:30

well there went half an hour

reborg16:03:33

2 pair of eyes 🙂

liamd16:03:36

haha thank you so much

joshkh16:03:38

i think you misspelled lanterna in your (ns clogue.display.ascii-window (:require [lantera.screen :as s]))

dpsutton16:03:57

rubber duck is real

liamd17:03:51

if i could dump some more code on y'all

(defn draw-state [entities]
  (let [size (s/get-size @screen)
        width (first size)
        height (second size)]
    (do 
      (debug "screen is " width " by " height)
      (for [x (range width)]
        (for [y (range height)]
          (let [glyph (get-glyph x y entities)]
            (do 
              (debug (str "drawing " glyph " at " x " " y))
              (s/put-string @screen x y )))))))
  (s/redraw @screen)
  (s/get-key-blocking @screen)) 

liamd17:03:06

i'm only seeing the "screen is..." message in the terminal

liamd17:03:11

am i missing something about for?

liamd17:03:33

i tried it out in the repl and i think this should work

liamd17:03:51

❰liamdyer❙~/mydev/clogue❱✔≻ lein run
18-03-05 17:14:16 TC-HQ-MBP--6396-William-Dyer DEBUG [clogue.display.ascii-window:25] - screen is  80  by  24

reborg17:03:59

@liamd you could try a doall before the first for

liamd17:03:26

ohhh it could be a laziness problem?

liamd17:03:07

well that got me an NPE so that's good

reborg17:03:28

there are all the symptoms for a laziness thing

liamd17:03:03

it threw an NPE on

Caused by: java.lang.NullPointerException
	at clojure.lang.Numbers.ops(Numbers.java:1013)
	at clojure.lang.Numbers.isPos(Numbers.java:96)
	at clojure.core$dorun.invokeStatic(core.clj:3036)
	at clojure.core$doall.invokeStatic(core.clj:3039)
	at clojure.core$doall.invoke(core.clj:3039)
	at clogue.display.ascii_window$draw_state.invokeStatic(ascii_window.clj:24)

liamd17:03:12

why is doall checking for a positive?

reborg17:03:17

that's likely happening elsewhere (educated guess)

liamd17:03:16

oh doall takes [n coll]

Scot17:03:29

Small note, you don't need nested for statements, (for [x (range width) y (range height)] ...) should iterate through all possible x y combinations

liamd17:03:51

looks like doall thought my debug statement was the n arg

liamd17:03:03

here:

(defn dorun
  "When lazy sequences are produced via functions that have side
  effects, any effects other than those needed to produce the first
  element in the seq do not occur until the seq is consumed. dorun can
  be used to force any effects. Walks through the successive nexts of
  the seq, does not retain the head and returns nil."
  {:added "1.0"
   :static true}
  ([coll]
   (when-let [s (seq coll)]
     (recur (next s))))
  ([n coll]
   (when (and (seq coll) (pos? n))
     (recur (dec n) (next coll)))))

liamd17:03:21

debug returned nil and then (pos? n) threw the NPE

Scot17:03:56

yeah, you wanna wrap just the for statement in doall

Scot17:03:17

(debug ...) (doall (for ...))

bronsa17:03:24

@liamdlooks like you’re using for for side effects

bronsa17:03:42

for is lazy list comprehension, it has nothing to do with the for you might be used in C-like languages

bronsa17:03:48

don’t use for for that

bronsa17:03:51

use doseq/`loop/recur`

liamd17:03:00

i assumed it was like a side-effecty map

bronsa17:03:08

that’s doseq

Scot17:03:09

The advantage of for is the binding forms it allows you. e.g.

(for [x [0 1 2 3 4 5]
      :let [y (* x 3)]
      :when (even? y)]
  y)

liamd17:03:03

cool swapping in doseq for for got rid of doall

sundarj17:03:47

there is actually a side-effecty version of map, it's run! e.g. (run! prn [1 2 3])

reborg17:03:35

@scot-brown you can in doseq too

reborg17:03:51

(doseq [x [0 1 2 3 4 5]
      :let [y (* x 3)]
      :when (even? y)]
  (println y))

liamd17:03:58

oh hell yeah http://recordit.co/lwB0sOT0vh thanks everyone

Scot17:03:12

@reborg cool, good to know!

Scot17:03:30

(I don't use for often 😛)

reborg17:03:14

rule of thumb: nested maps === for

reborg17:03:41

(as in (map f (map g coll)))

Elena18:03:26

I'm spec'ing. How do I spec an argument that can be any of the clojure.core functions? e.g. inc

Elena18:03:10

I should specify that I already tried ifn? and that is not correct

Cayetano Soriano19:03:15

Hi any suggestion for an event dispatcher in clojure?

seancorfield19:03:53

@elena.caraba Can you clarify how ifn? "is not correct"?

Elena19:03:59

@seancorfield The error I get back is "java.lang.RuntimeException: Map literal must contain an even number of forms "

seancorfield19:03:33

@elena.caraba OK, so that says your syntax isn't correct -- but isn't related to ifn? Can you share youre code?

Elena19:03:46

In my example, the function is "inc" from clojure.core

seancorfield19:03:15

Please show your code -- I think you just have a syntax error in your spec.

Russ Olsen19:03:34

@elena.caraba Specifically it's saying that you have a map that has a key w/o a value (or a value without a key, depending on how you look at it), something like {:name "russ" :age}

Elena19:03:14

@russ767 I think you may be right. So does this mean that spec-ing is discovering errors in my source code?

dpsutton19:03:40

you're not hitting spec yet. you're seeing an error from the reader. you've got a malformed map literal somewhere. and i think @seancorfield is right that it might be in your spec

Russ Olsen19:03:35

Right, this is the kind of error you get as the code is being read in right at the start.

mfikes20:03:24

@elena.caraba right, that {:pre ...} map needs one value. (Put all of those spec/valid? calls in one larger vector.)

mfikes20:03:57

I think you want

{:pre  [(spec/valid? m/array? m)
        (spec/valid? int? i)
        (spec/valid? int? j)
        (spec/valid? ifn? fct)]}

mfikes20:03:05

It also seems the preconditions are referring to i and j, which aren’t args. But, as an aside @elena.caraba what you are doing can also be done via instrumentation in spec. (You can write a spec that says that dosmth’s args must comply with some specs, and then enable “instrument” the dosmth fn at runtime—typically at dev time.)

Elena20:03:07

@mfikes pulling them all in one vector worked, though I don't understand why... i, j are supposed to be r,c

mfikes20:03:40

Well, typically :pre applies some preconditions to the arguments of the function

mfikes20:03:33

An example:

(defn square [x]
  {:pre [(number? x)]}
  (* x x))

mfikes20:03:45

In this example, the precondition is on the argument x

mfikes20:03:44

Oh, I misunderstood your comment @elena.caraba: All of the preconditions that you want to apply are put into a single vector

mfikes20:03:27

This allows for a syntax where you have all of the preconditions in that map under :pre and all of the postconditins under another key :post

Russ Olsen20:03:40

@mfikes Gotta love that url.

mfikes20:03:21

It is making me hungry for M&Ms

Kara21:03:29

I'm getting a strange linter error... in my code I have (Math/floor (/ (- score 10) 2)) which is working when I run it... however my linter is complaining that it is unable to resolve symbol Math ... do I have to define Math somewhere? I was a bit confused on how to call it... but it seemed to just work.

noisesmith21:03:07

your linter is bad if it doesn't recognize interop in scope

Kara21:03:35

ok. I'm cool with just ignoring it... I just wanted to make sure I wasn't supposed to explicitly import it into the namespace or something

noisesmith21:03:49

also "unable to parse" is weird here - I mean it's a valid clojure symbol

Kara21:03:02

oops my bad resolve

Kara21:03:07

I guess I was unable to parse 😉

noisesmith21:03:26

java.lang.* is always in scope in jvm clj

Kara21:03:47

this is clojurescript... would that change anything?

noisesmith21:03:52

now you might have an issue in a cljc file, and definitely in a cljs file - but it's always valid to use Math/* in clj

noisesmith21:03:11

yes, it should be js/Math

mfikes21:03:18

You can also use Math/ in cljs as well

mfikes21:03:32

Math is a pseudonamespace in cljs

noisesmith21:03:35

oh, cool - but I'm less surprised with a cljs linter not recognizing Math/

Kara21:03:15

ok sounds like it's just the linter is a bit confused then. I just wanted to make sure it wasn't "magically" working due to something local on my system that would break later. 🙂

noisesmith21:03:51

I just discovered the (. Math floor x) form works in clj, but not in cljs

noisesmith21:03:14

(that's a lower level form of interop syntax, mostly only useful in macros)

noisesmith21:03:55

also (.floor Math x) works in cljs, but not clj

Kara21:03:16

Yeah, I had found https://cljs.github.io/api/syntax/Math-namespace ... which made it sound like Math/ should just work... but it was a little confusing to me where this namespace is...

noisesmith21:03:44

oh wow, that's quite the special case, haha

mfikes21:03:58

Yeah, it is a lot like js/

noisesmith21:03:58

it's like, the only built in js class treated that way

Kara21:03:20

so really it would be similar to (.floor js/Math) ?

Kara21:03:30

it's just... wierdly namespaced?

noisesmith21:03:38

right (.floor js/Math x) works

noisesmith21:03:01

it's like an implicit pseudo-namespace, as a special case

Kara21:03:12

cool. odd... but cool 🙂

mfikes21:03:43

It makes writing portable .cljc code a little easier. And it is easier to context switch between Clojure and ClojureScript as a human.

Kara21:03:33

I could see that. I'm working pretty much exclusively with ClojureScript since I'm working with react-native, but that makes sense in terms of context switching

mfikes21:03:40

Oh, @kara also, if you weren't aware, there is a #cljsrn channel for React Native-specific stuff if you encounter any

Kara21:03:19

Yes, I've been over there. 😉 I decided... hey you know what I should do? Learn react native and clojurescript and mobile development at the same time 😄

Kara21:03:26

it's been slow... but I'm inching along

mfikes21:03:44

Just don't add Emacs to that list.

Kara21:03:57

oh no! I'm on atom thanks. I'll take the heat