beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
mzuppichin 2020-12-10T12:38:57.256200Z

Hello everybody, Clojure noob here. I have been kicked off 4Clojure Android app and can't login to my user anymore, however credentials are correct and he browser access goes smooth as usual. Has anyone experienced the same behaviour? Thanks sincerely in advance!

roelof 2020-12-10T13:13:48.256800Z

oke, and another problem

(defn isPrime? [n known]
  (loop [cnt (dec (count known)) acc []]
    (if (< cnt 0) (not (any? acc))
        (recur (dec cnt) (concat acc [(zero? (mod n (nth known cnt)))])))))


(defn my_primes
  "my version to print out primes to a certain number"
   [limit]
   (map #(isPrime? % []) (range 2 .. limit ))
  )

roelof 2020-12-10T13:14:08.257200Z

error :

; Syntax error compiling at (chapter4.clj:32:26).
; Can't take value of a macro: #'clojure.core/..

2020-12-10T13:17:17.257700Z

You don't need the .. in your range function, and in fact .. means something else in Clojure

2020-12-10T13:19:12.258400Z

Just do (range 2 limit)

roelof 2020-12-10T13:19:17.258700Z

thanks

roelof 2020-12-10T13:19:59.260100Z

and there is another error. I was hoping on seeing all the prime-numbers but I see now a collection of false 😢

ryan echternacht 2020-12-10T13:22:42.260500Z

you want filter not map

2020-12-10T13:23:48.262Z

I would say test your isPrime? function first and make sure it returns true when you give it a prime number and false (or nil) when you give it a non-prime number.

roelof 2020-12-10T13:24:16.262400Z

I tried that one also but then I see a empty collection. So I assume my isPrime is wrong.

roelof 2020-12-10T13:25:27.263Z

yep, that one is not good. It gives false on (isPrime 3 [])

roelof 2020-12-10T13:25:49.263500Z

so back to the drawing board how I can test if a number is a prime

roelof 2020-12-10T13:35:26.264600Z

what do you think of my solutions . I did only study the 4 first chapters of the Clojure from the ground up site

2020-12-10T13:46:47.269Z

The code looks good overall. A couple style points: you are using partial correctly, but there was a discussion recently about using (partial foo) versus using #(foo %) and a lot of folks favor using #(foo %) in most cases because it’s more versatile and also slightly more efficient. Also it’s idiomatic to use shorter names like coll and pred instead of spelling out collection and predicate (though I favor using longer, more explicit names personally, except for really common terms like coll and pred).

roelof 2020-12-10T13:47:53.269200Z

oke

roelof 2020-12-10T13:48:33.270300Z

so If I understand you well I could change this (partial divisible? n) to #(divisible? n) ?

2020-12-10T13:48:56.270800Z

You need to add the % at the end

2020-12-10T13:49:23.271100Z

but yeah, that’s what I was referring to

roelof 2020-12-10T13:49:49.271600Z

oke, so #(divisible? n %) ?

2020-12-10T13:49:58.271800Z

Right

2020-12-10T13:50:42.272300Z

Oh, and it’s also conventional to use dashes in names instead of underscore.

2020-12-10T13:51:16.273100Z

so count-occurences instead of count_occurences, and my-filter and my-primes

2020-12-10T13:51:49.273500Z

Clojure folks are too lazy to hold down the shift key 😄

roelof 2020-12-10T13:51:55.273700Z

thanks, changed also

roelof 2020-12-10T13:52:37.274500Z

I know there are also languages who use countOccurences . I do not like that

roelof 2020-12-10T13:53:25.275Z

but clojure folks love parentheses 😛

2020-12-10T14:00:30.275200Z

🙂

2020-12-10T14:01:02.275900Z

It’s actually the same number of parens in a lot of cases, it’s just that the first paren comes to the left of the function name instead of to the right.

2020-12-10T14:01:32.276200Z

Just like HTML does with < and >.

roelof 2020-12-10T14:03:46.276800Z

now take a break and tomorrow macros seems to be a difficult subject

roelof 2020-12-10T14:04:08.277300Z

im following the plan which clojurefarm has made

roelof 2020-12-10T14:05:28.278800Z

I hope i once learn as much clojure I can make a website with it and solved the difficult challenges of Advent of Code or exercism

2020-12-10T14:06:16.279500Z

Macros can be really hard to wrap your head around, but honestly I've been using Clojure for years and years, and I've written maybe 3 macros total (not counting "let's write a macro!" exercises)

roelof 2020-12-10T14:06:41.279700Z

oke

roelof 2020-12-10T14:08:07.280200Z

I have read that you almost never write a macro

roelof 2020-12-10T14:08:35.281200Z

but there are three challenges at the end that you challenge to write a macro I think

roelof 2020-12-10T14:08:39.281600Z

Using the threading macros, find how many numbers from 0 to 9999 are palindromes: identical when written forwards and backwards. 121 is a palindrome, as is 7447 and 5, but not 12 or 953.

Write a macro id which takes a function and a list of args: (id f a b c), and returns an expression which calls that function with the given args: (f a b c).

Write a macro log which uses a var, logging-enabled, to determine whether or not to print an expression to the console at compile time. If logging-enabled is false, (log :hi) should macroexpand to nil. If logging-enabled is true, (log :hi) should macroexpand to (prn :hi). Why would you want to do this check during compilation, instead of when running the program? What might you lose?

2020-12-10T14:08:42.281700Z

Yeah most of the time a good function is all you ever need. Plus you can't pass a macro around like you can a function.

2020-12-10T14:09:41.282400Z

Two of those require you to write your own macro; the first one just wants you to use some of the built-in macros.

2020-12-10T14:10:33.283700Z

Just remember: macros write code, they don't do anything to your runtime data.

2020-12-10T14:10:58.284600Z

A macro is a tiny program that writes bits of other programs.

roelof 2020-12-10T14:11:22.285100Z

we see tomorrow. I hope I can ask for help here if needed or for a review. I hope I will not ask for help too much but the error messages are for me not always clear and as I said im totally new in Clojure so I think I need a lot of help to learn it wel

roelof 2020-12-10T14:12:01.285900Z

oke

2020-12-10T14:12:18.286600Z

Yeah, the error messages are a sore spot but they're getting better, and after a while you kind of get to recognize patterns of "Oh, I got this kind of error message, I should check, that"

2020-12-10T14:12:29.287100Z

but some of them stump even the best of us.

roelof 2020-12-10T14:12:31.287200Z

so this one makes the function (f a b c) ??

2020-12-10T14:12:46.287400Z

Yeah, that's a good use for a macro.

2020-12-10T14:13:13.287800Z

"Build Your Own defn" 🙂

roelof 2020-12-10T14:17:27.288100Z

sorry I mean this one :

Write a macro id which takes a function and a list of args: (id f a b c), and returns an expression which calls that function with the given args: (f a b c).

roelof 2020-12-10T14:20:30.289100Z

it schould look like this It hink

(defmacro id [fun a b c]
  (fun a b c)

roelof 2020-12-10T14:27:59.289300Z

@manutter51

2020-12-10T14:35:36.291400Z

You’ll need to add some macro-specific syntax to that so that it doesn’t just execute (fun a b c) when you call it, but that’s actually a good start: you’ve written out what you want the end result to be when your macro executes, and now you just have to convert it into the body of an actual macro.

roelof 2020-12-10T14:44:16.292100Z

hmm, the only thing I can find it to change it into this :

(defmacro id [fun a b c] (fun a b c)``

2020-12-10T14:46:56.293200Z

You’re short a ) at the end, but once you add that, try running in your REPL with (macroexpand '(id foo a b c))

2020-12-10T14:47:48.293400Z

Then try (macroexpand '(id + 1 2 3))

roelof 2020-12-10T14:57:34.293700Z

on both I see this in repl

clj::chapter4=> 
(chapter4/fun chapter4/a chapter4/b chapter4/c)

roelof 2020-12-10T14:57:45.294Z

no idea if this is allright

2020-12-10T14:59:06.295100Z

For the second one you should see (+ 1 2 3), (possibly with the clojure namespace attached to the + symbol). So there’s something not quite right with your macro.

roelof 2020-12-10T14:59:52.295800Z

I think so

alexmiller 2020-12-10T14:59:54.295900Z

you need unquotes

alexmiller 2020-12-10T15:00:03.296200Z

~a ~b ~c

alexmiller 2020-12-10T15:00:38.296500Z

you are currently putting a literal symbol a b c in the expanded code

roelof 2020-12-10T15:01:48.297Z

then I think I also need to unquote the fun

☝️ 1
alexmiller 2020-12-10T15:02:08.297500Z

yeah sorry, that too

roelof 2020-12-10T15:02:23.297800Z

(defmacro id [fun a b c]
  `(fun ~a ~b ~c))
gives now with :
(macroexpand '(id + 1 2 3))

roelof 2020-12-10T15:02:37.298100Z

clj::chapter4=> 
(chapter4/fun 1 2 3)

2020-12-10T15:03:15.298500Z

You’re getting closer

roelof 2020-12-10T15:03:21.298700Z

yep, unquote everything does the job

roelof 2020-12-10T15:03:35.299100Z

(defmacro id [fun a b c]
  `(~fun ~a ~b ~c))

roelof 2020-12-10T15:03:39.299300Z

is the solution

roelof 2020-12-10T15:04:13.300Z

I learn here more then on the clojurefarm channel 🙂

2020-12-10T15:04:36.300400Z

If you want a challenge, you could try to modify your id macro so that it takes zero or more arguments.

bronsa 2020-12-10T15:05:21.300700Z

or not to use syntax-quote

2020-12-10T15:05:52.301200Z

A macro without a syntax quote?? 😱

bronsa 2020-12-10T15:06:16.301400Z

syntax quote is never needed

2020-12-10T15:06:35.301800Z

Heh, I can see how to do that but still 😱

roelof 2020-12-10T15:07:34.302300Z

with variable amount of arguments

roelof 2020-12-10T15:07:38.302600Z

(defmacro id [fun & args]
  `(~fun ~args))

2020-12-10T15:07:57.303200Z

Close, you need a slightly different unquote for the args bit

roelof 2020-12-10T15:08:42.303600Z

chips , I see

clj::chapter4=> 
(+ (1 2 3))

2020-12-10T15:10:02.304300Z

Do you have a reference/tutorial for defmacro? It should show you the list of unquote symbols.

roelof 2020-12-10T15:11:06.304600Z

I onu have this page : https://aphyr.com/posts/305-clojure-from-the-ground-up-macros

roelof 2020-12-10T15:11:30.305100Z

I tried rhis :

(defmacro id [fun & args]
  `(~fun ~& args))

roelof 2020-12-10T15:11:44.305500Z

but that one gives a syntax error

Darin Douglass 2020-12-10T15:12:30.305800Z

have you tried ~@args?

Darin Douglass 2020-12-10T15:13:02.306400Z

the @ essentially is apply for macros

roelof 2020-12-10T15:13:07.306700Z

yep

roelof 2020-12-10T15:13:19.307300Z

also a syntax error :

(defmacro id [fun & args]
  `(~fun ~&args))

2020-12-10T15:13:36.307600Z

That’s the “unquote-splice” symbol, btw, and notice it’s @ not &

alexmiller 2020-12-10T15:14:28.308800Z

a macro is literally just a function that takes code (as a data structure) and returns replacement code (as a data structure)

roelof 2020-12-10T15:14:42.309400Z

yes, this does it :

(defmacro id [fun & args]
  `(~fun ~@args))

roelof 2020-12-10T15:15:04.310Z

without the unquote I do not have a idea how to make that work as a beginner

alexmiller 2020-12-10T15:15:49.310800Z

so you just want a function that does: (id + 1 2 3) -> (+ 1 2 3)

roelof 2020-12-10T15:16:16.312300Z

yep, that is I the challenge as I understand it

alexmiller 2020-12-10T15:16:17.312400Z

args is a seq (1 2 3) so you're almost there. how do you prepend something to a list?

roelof 2020-12-10T15:16:36.312600Z

conj

alexmiller 2020-12-10T15:16:43.312800Z

there you go (or cons)

alexmiller 2020-12-10T15:17:33.313400Z

(defmacro id [fun & args]
  (conj args fun))

roelof 2020-12-10T15:17:58.314300Z

that simple. I was overthinking it

alexmiller 2020-12-10T15:17:59.314400Z

or

(defmacro id [fun & args]
  (cons fun args))    ;; order is different

bronsa 2020-12-10T15:18:44.315700Z

people often think that macros are this special thing in clojure that needs syntax-quote and vice versa, but macros are literally just functions, and syntax-quote is literally just a templating syntax for data

roelof 2020-12-10T15:18:48.315900Z

Time to make a lot of notes and take a break. Tomorrow further on this for me unknown territory

alexmiller 2020-12-10T15:19:36.316200Z

you can find examples of both styles in clojure core

alexmiller 2020-12-10T15:20:08.316700Z

look at (source when) or (source and) for a couple good examples to study

roelof 2020-12-10T15:21:56.318500Z

hmm, in your examples source is unknown when I do it in repl @alexmiller

bronsa 2020-12-10T15:22:05.318700Z

a good exercise is also to forget about defmacro and just implement normal functions with defn , and just invoke the function with quoted arguments manually (e.g. (foo 'bar '1 '[1 2 3]) instead of (foo bar 1 [1 2 3]))

bronsa 2020-12-10T15:22:21.319100Z

then to turn foo into a macro you just need to remove the quotes from the invocation and replace defn with defmacro

alexmiller 2020-12-10T15:23:01.319600Z

you might need to (use 'clojure.repl) if you're not in user namespace

alexmiller 2020-12-10T15:23:35.320200Z

source is in clojure.repl

roelof 2020-12-10T15:25:17.320400Z

thanks

roelof 2020-12-10T15:25:43.320900Z

This help from this channel gives me hope. I maybe can learn clojure

roelof 2020-12-10T15:25:51.321100Z

Time for a break

roelof 2020-12-10T15:26:47.321400Z

but im impressed by the speed

roelof 2020-12-10T15:27:39.322Z

maybe somewhere in 2021 I will be able to try to solve AOC challenges on my own

roelof 2020-12-10T15:27:54.322500Z

but till I be there I have a lot to learn

alexmiller 2020-12-10T15:28:16.322800Z

you're almost done

roelof 2020-12-10T15:28:24.323200Z

What do you think of the brave book

2020-12-10T15:28:37.323700Z

:thumbsup:

alexmiller 2020-12-10T15:28:38.323800Z

it's all just more functions

roelof 2020-12-10T15:29:05.324800Z

almost done. I m now busy for 2 days.

2020-12-10T15:29:06.324900Z

Most people who have used the Brave & True book have been pleased with it

2020-12-10T15:29:25.325900Z

there’s also a #braveandtrue channel here specifically for that book/website

roelof 2020-12-10T15:29:28.326Z

Can image I know now enough to do exercism or AOC puzzles

alexmiller 2020-12-10T15:30:08.326700Z

Keep https://clojure.org/api/cheatsheet open

roelof 2020-12-10T15:30:10.326800Z

and I have to learn a framework if I want to make websites and learn how to store something in a database

roelof 2020-12-10T15:30:42.327200Z

I cannot image that I now almost done , sorry

2020-12-10T15:32:18.328Z

It took me a few months to get really comfortable with Clojure, but that was back before Slack and also I was new to the whole “functional programming” thing.

Lars Nilsson 2020-12-10T15:33:58.329300Z

I tried to start using Clojure when it was really new, but the lack of leiningen, etc., at the time made it too painful to be productive, and gave it up for a couple of years. Then came back to it when the tooling was much improved.

2020-12-10T15:34:21.329600Z

Yeah, leiningen was a big help at the time.

roelof 2020-12-10T15:36:25.330100Z

im comimng from ruby and haskell so the functional part is not new to me

roelof 2020-12-10T15:37:01.331100Z

I have to get used to the parentheses and the polish notation as they call it

Lars Nilsson 2020-12-10T15:37:22.331500Z

I had been using Ocaml quite a bit before Clojure, so same here regarding the functional aspect.

roelof 2020-12-10T15:38:51.332600Z

I think in the future I will have the most problems when I want to use something as reframe. Never wrote javascript or react or something before

roelof 2020-12-10T15:39:02.333Z

but we see when we get there

2020-12-10T15:41:06.334800Z

I love re-frame, but yeah react does have a few quirks, and also cljs isn’t 100% identical to clj, so there’s bits that may bite the unwary. I’m working full time doing clj+cljs+re-frame tho, so there’s more than plenty enough to get a decent web app up and running.

roelof 2020-12-10T15:42:44.336Z

im thinking if and when I got to that point to make a website which uses the Rijksmuseaum api . where someone sees a page and in the same time the images are downloaded and they replace the placeholders

2020-12-10T15:44:34.336500Z

Hmm, I’ve done that in straight JS back in the day, never tried to do in cljs :thinking_face:

2020-12-10T15:46:02.336900Z

replace placeholder images with hi-res versions that is

roelof 2020-12-10T15:47:05.337800Z

is there then a big difference in cjs and reframe. The way the clojurefarm is teaching us clojure is using reframe

2020-12-10T15:49:09.338600Z

Re-frame is a library that uses CLJS. It’s not part of Clojure or CLJS, it’s just popular.

clyfe 2020-12-10T15:49:31.339200Z

What is clojurefarm?

2020-12-10T15:50:27.340Z

Basically, React exists in the world of JS, and someone wrote a CLJS library named “reagent” to make it easier to use React in CLJS, and then someone else wrote a library named “re-frame” on top of reagent.

roelof 2020-12-10T15:52:13.340500Z

@claudius.nicolae see this page : https://github.com/athensresearch/ClojureFam

👍 1
roelof 2020-12-10T15:54:46.341300Z

oke, I see when I get there

roelof 2020-12-10T15:55:39.342400Z

first this "book", then the brave book and then 4 clojure and then I think things like reframe i have to learn

roelof 2020-12-10T15:56:00.342900Z

and im not in a hurry because this is a hobby of mine and not for a job

roelof 2020-12-10T15:56:20.343400Z

no idea if there are clojure jobs in the Netherlands

roelof 2020-12-10T16:08:39.343800Z

maybe I come tomorrow or later back to see how to solve this one :

Advanced) Using the rationalize function, write a macro exact which rewrites any use of +, -, *, or / to force the use of ratios instead of floating-point numbers. (* 2452.45 100) returns 245244.99999999997, but (exact (* 2452.45 100)) should return 245245N

2020-12-10T16:28:52.346200Z

Greetings! Can't find an elegant way to do a partial flatten, by which I mean a function that accepts any nesting of sequences and returns a sequence of the innermost sequences ; e.g. (partial-flatten [[[1 2]] [[[3 4]]]]) => ([1 2] [3 4]. Could a kind puzzle-inclined person help me out?

2020-12-10T16:42:29.346500Z

Don't

2020-12-10T16:42:55.347200Z

This is exactly why using flatten of any stripe is a bad idea

alexmiller 2020-12-10T17:02:44.348300Z

you could do it with either tree-seq (save only colls that don't contain colls) or postwalk (concat any colls that only contain colls)

2020-12-10T17:11:11.348700Z

Care to elaborate?

2020-12-10T17:14:24.348900Z

because you always end up with "I want to flatten this, but...."

2020-12-10T17:14:54.349100Z

but I only want to flatten n levels, I only want to flatten when the lists don't contain x, etc

roelof 2020-12-10T17:16:11.349700Z

Are there here people who are doing the AOC challenges ?

🖐️ 4
2020-12-10T17:16:30.349800Z

in general flatten get used when you write a program of the form 1. do some stuff that builds up some nested list 2. flatten things out

2020-12-10T17:17:48.350300Z

but while step #1 is a generally steeped in context, by the time you get to step #2 the context has been thrown away, so determining how and where to flatten has to be done all over again

dorab 2020-12-10T17:18:06.350600Z

@roelof See the #adventofcode channel in this Slack.

2020-12-10T17:18:19.350700Z

while if you just applied concat here and there while doing #1, you had the context right there to easily make the decisions

2020-12-10T17:20:55.351Z

Fair point. In this instance, the nesting comes from using (for) in a (loop ...) which ends up nesting the results arbitrarily - or rather, in an input dependent, yet useless way. It would be indeed better not to use flatten-but-x to solve this. OTOH, using for [ ... :let ... :when ... ] is super terse and expressive.

2020-12-10T17:21:34.351200Z

for doesn't arbitrarily nest things

2020-12-10T17:21:52.351500Z

you are recursively calling a function which uses for

2020-12-10T17:22:22.351700Z

for nests things once. the recursion over it can be n-deep with varying ns

2020-12-10T17:22:41.351900Z

right

2020-12-10T17:22:44.352100Z

it's a for [ ... ] recur

2020-12-10T17:22:56.352300Z

the context here is you know when you recur, so unwrap it there

2020-12-10T17:24:10.352500Z

I tried to do that, but probably got it wrong. I'll do more attempts rn.

2020-12-10T17:24:39.352700Z

for example, if you have (for [i (f x)] i) and (f x) returns a lists of lists then do (for [i (f x) ii i] ii)

2020-12-10T17:31:36.352900Z

it's more like (defn f [a prefix] (comment omitted termination code)) (for [n (magic a)] (f (drop n a) (conj prefix (first a))))). (magic) returns a small number.

2020-12-10T17:32:21.353100Z

right, so shift the recursive call up into the for

2020-12-10T17:33:05.353400Z

(defn f [...] ... (for [... i (f ...)] i))

2020-12-10T17:33:36.353600Z

ha.

2020-12-10T17:34:37.353800Z

that will concat one level of lists for every recursive call, so in your base case you may need to add a second layer of lists if your lists is meant to be a list of lists

2020-12-10T17:36:28.354Z

the recursive call chain ends up being exactly the context information you would need to recover in your "flatten, but..."

2020-12-10T17:36:37.354200Z

that worked.

2020-12-10T17:37:10.354400Z

it better, I am a big fan of recursive fors like that

2020-12-10T17:37:25.354600Z

I followed your instructions and that made it work. I don't understand how or why it works tho :thinking-face:

2020-12-10T17:40:16.354800Z

for is a combination of a lot of difference sequence functions, include map and mapcat

2020-12-10T17:40:59.355Z

(for [i x] (f i)) => (map f x)

2020-12-10T17:41:53.355200Z

so far so good.

2020-12-10T17:42:33.355400Z

(for [i x ii (f i)] (g ii)) => (map g (mapcat f x))

2020-12-10T17:43:20.355700Z

(for [x xs y ys] [x y]) => ([x0 y0] [x0 y1] .. [x0 yN] [x1 y0] .. [xN yN]) - cartesian product I believe

2020-12-10T17:45:30.356Z

(for [x xs y ys] [x y]) => (mapcat (fn [x] (map (fn [y] [x y]) ys)) xs)

2020-12-10T17:46:33.356200Z

oooh.

2020-12-10T17:49:20.356400Z

[ processing intensifies ... ]

2020-12-10T17:49:46.356600Z

any for that doesn't use any of the keyword stuff (:when, :while, etc) can be transformed into an expression of nested mapcats around an inner map, you can do the keyword stuff to you just have to sprinkle in some calls to filter and take-while

2020-12-10T17:51:50.356800Z

(and of course (map f x) <=> (mapcat (comp list f) x) )

2020-12-10T17:52:12.357Z

eloquently put.

2020-12-10T17:52:23.357200Z

this belongs to clojuredocs!

2020-12-10T18:03:48.357400Z

(macroexpand '(for [x xs y ys] [x y])) is significantly harder to grok thank your explanations 🙂

2020-12-10T18:04:12.357700Z

Thank you very much for your time and eloquent explanation

roelof 2020-12-10T19:58:05.358200Z

is there a easy way to make this work :

(ns chapter5)

(defn schedule
  "Using the control flow constructs we've learned, write a schedule 
   function which, given an hour of the day, returns what you'll be 
   doing at that time. (schedule 18), for me, returns :dinner."
  [my-time]
  (cond
    (&lt;= "0:00" my-time "07.00")   :sleeping
    (== "07:00" my-time)          :breakfast
    (&lt;= "07:01" my-time "12:00")  :work
    (= "12:00" my-time)                  :lunch 
    (&lt;= "12:01" my-time "18:00")  :more-work
    (&lt;=  "18:01" my-time "19:00") :dinner
    (&lt;= "19:01" my-time "23:59")  :watching-tv    
    ))

roelof 2020-12-10T19:58:56.358900Z

is there a way I can convert the given time and the comparisaion to a time object

roelof 2020-12-10T19:59:33.359700Z

Right now I only have studied the first 5 chapters of the "Clojure from the ground up " tutorial

2020-12-10T20:03:49.361800Z

I find java time tricky to work with, I think for this particular exercise I’d convert the numeric input to a string

dorab 2020-12-10T20:05:09.363200Z

@roelof take a look at the compare function. For just this limited set of string comparisons, it should be adequate.

2020-12-10T20:05:35.363800Z

isn't compare what &lt;= is using already? never mind, it only works on numbers

roelof 2020-12-10T20:06:49.366Z

Hmm, have to think how compare could help me

roelof 2020-12-10T20:07:19.367100Z

@manutter51 the trick to make it all string could help

👍 1
2020-12-10T20:07:48.367900Z

@roelof

(compare "0:00" "07:00") =&gt; 3

2020-12-10T20:08:02.368500Z

you can do two comparisons per case, or if you feel clever do a binary search

roelof 2020-12-10T20:09:03.370400Z

?? I want to check if the given time is between two other times

2020-12-10T20:09:19.370900Z

right, and using compare twice can tell you if it is

salam 2020-12-10T20:09:35.371100Z

this is so far the best date-time api i've ever worked with. so if you want to do it right (like how you would do it in a real-world project), i would suggest taking a look at this api.

2020-12-10T20:09:44.371600Z

if they are strings

roelof 2020-12-10T20:10:03.372100Z

oke

enforser 2020-12-10T20:10:22.372700Z

Why not just represent time of day in minutes as a number? No need to introduce string comparisons here

(defn time-as-minutes [hour minute] (+ minute (* 60 hour))

(defn schedule [my-time-in-minutes] 
  (cond 
    (&lt;= (time-as-minutes 0 0) my-time-in-minutes (time-as-minutes 7 0)) :sleeping
    ;; add the rest of the cases
    ))

👍 1
2020-12-10T20:10:23.372800Z

for a given pair of times, you'd want the first compare to return positive or zero, and the second compare to return negative or zero

roelof 2020-12-10T20:10:47.373100Z

so I can do (localtime my_time) to convert the given time to a time object

roelof 2020-12-10T20:11:02.373300Z

so I have to that for all the times

roelof 2020-12-10T20:11:59.374Z

@trailcapital that is also a good idea

salam 2020-12-10T20:12:29.374100Z

(java.time.LocalTime/parse "07:00")
#object[java.time.LocalTime 0x2b87581 "07:00"]
(str *1)
"07:00"

roelof 2020-12-10T20:15:27.374300Z

oke, and then I can use isbefore and isafter to check if its in the interval

roelof 2020-12-10T20:15:35.374500Z

Time to play with this idea

salam 2020-12-10T20:19:09.374800Z

yup

salam 2020-12-10T20:21:00.375Z

just as an example, for the first clause in your cond:

(def midnight (java.time.LocalTime/MIDNIGHT))
#'user/midnight

(def breakfast-time (java.time.LocalTime/parse "07:00"))
#'user/morning

(def my-time (java.time.LocalTime/parse "06:30"))
#'user/my-time

(and (.isAfter my-time midnight)
     (.isBefore my-time breakfast-time))
true

roelof 2020-12-10T20:24:15.375500Z

oke I was trying another idea but get errors

(ns chapter5)

(defn parse-time
  "Parse a string to a time object"
   [time-string]
   (java.time.LocalTime/parse time-string))

(defn schedule
  "Using the control flow constructs we've learned, write a schedule 
   function which, given an hour of the day, returns what you'll be 
   doing at that time. (schedule 18), for me, returns :dinner."
  [my-time]
  (cond
    (&lt;= (parse-time "00:00") (parse-time(str my-time)) (parse-time "07:00") )   :sleeping
    ))

(schedule "03:00")
error :
; Execution error (ClassCastException) at chapter5/schedule (form-init11789170975546566471.clj:9).
; class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')

dharrigan 2020-12-10T20:26:10.376100Z

If you wanted to use the built-in (jvm) time library, perhaps this might be suitable...

dharrigan 2020-12-10T20:26:21.376300Z

(ns foo
  (:import [java.time LocalTime]))

(defn parse
  [my-time]
  (LocalTime/parse my-time))

(def breakfast (parse "07:00"))
(def midday (parse "12:00"))
(def nearly-dinner (parse "18:00"))
(def dinner (parse "19:00"))
(def late-night (parse "23:59"))

(defn schedule
  "Using the control flow constructs we've learned, write a schedule
   function which, given an hour of the day, returns what you'll be
   doing at that time. (schedule 18), for me, returns :dinner."
  [my-time]
  (let [my-time' (parse my-time)]
    (cond
     (.isBefore my-time' breakfast) :sleeping
     (= my-time' breakfast) :breakfast
     (.isBefore my-time' midday) :work
     (= my-time' midday) :lunch
     (.isBefore my-time' nearly-dinner) :more-work
     (.isBefore my-time' dinner) :dinner
     (.isBefore my-time' late-night) :watching-tv)))

(schedule "06:00")
(schedule "07:00")
(schedule "11:00")
(schedule "12:00")
(schedule "15:00")
(schedule "18:00")
(schedule "19:30")
(schedule "00:00")

salam 2020-12-10T20:26:32.376400Z

oh, you cannot use &lt;= with times...

salam 2020-12-10T20:26:55.376600Z

it's simply not overridden for those java time types...

salam 2020-12-10T20:27:26.376900Z

take a look at the example for how to do date-time comparison that i posted above....

roelof 2020-12-10T20:27:31.377200Z

Could also be working

roelof 2020-12-10T20:27:46.377600Z

I will play tomorrow with both ideas

roelof 2020-12-10T20:28:49.377700Z

oke, thanks , I will play with it tomorrow. its too late

salam 2020-12-10T20:28:55.377900Z

rule of thumb for when dealing with time: don't roll your own solutions because time is hard. 😉

roelof 2020-12-10T21:01:46.379100Z

why do I get this error:

(ns chapter5
  (:import [java.time LocalTime]))

(defn parse
  [my-time]
  (LocalTime/parse my-time))

(def breakfast (parse "07:00"))
(def midday (parse "12:00"))
(def nearly-dinner (parse "18:00"))
(def dinner (parse "19:00"))
(def late-night (parse "23:59"))

(defn schedule
  "Using the control flow constructs we've learned, write a schedule 
   function which, given an hour of the day, returns what you'll be 
   doing at that time. (schedule 18), for me, returns :dinner."
   [my-time] 
   let [my-time' (parse my-time)]
    (cond
     (.isBefore my-time' breakfast) :sleeping ))

(schedule "03:00")
error :
unresolved symbol my-time'

roelof 2020-12-10T21:03:45.379200Z

I never try to roll my own solution when there is something for it

Lars Nilsson 2020-12-10T21:04:05.379700Z

Need parens for the let?

salam 2020-12-10T21:06:12.381400Z

one exception is when your objective is learning how to do it. 🙂

dharrigan 2020-12-10T21:07:07.381900Z

yes, you're missing a parens just before the let, i.e., (let...

roelof 2020-12-10T21:07:44.382100Z

chips

roelof 2020-12-10T21:07:57.382600Z

now another one :

Could not locate chapter4__init.class, chapter4.clj or chapter4.cljc on classpath.

roelof 2020-12-10T21:08:29.383300Z

which do not make sense because chapter4.cjs in another file in the same directory

dharrigan 2020-12-10T21:08:44.383500Z

cjs?

roelof 2020-12-10T21:09:32.383700Z

sorry clj

dpsutton 2020-12-10T21:10:34.384Z

how did you trigger this error?

roelof 2020-12-10T21:11:12.385200Z

re-opened vs code and then do crtl-alt-c crtl-alt-j to start up a calva repl

alexmiller 2020-12-10T21:11:32.385700Z

I feel like you are not the first person here with this same error, wonder if maybe whatever repo you're using is not set up well

dpsutton 2020-12-10T21:11:57.386500Z

what command does ctrl-alt-c ctrl-alt-j run?

roelof 2020-12-10T21:12:16.387200Z

could be. I can push all my code to github so you can look ?

alexmiller 2020-12-10T21:12:22.387400Z

but it's saying exactly the problem - you're trying to load chapter4 ns but it's not on your classpath. presumably you have the file so it's something with the config of the classpath

dpsutton 2020-12-10T21:12:40.387800Z

dpsutton 2020-12-10T21:12:57.388300Z

this is what the maintainer and creator of calva mentioned yesterday to you

pez 2020-12-10T21:13:17.388800Z

@roelof I’d be happy to try your project out from the Calva perspective of things.

pez 2020-12-10T21:14:29.389800Z

As @alexmiller mentions, this problem shows up now and then. Might be a problematic project template, but also might be a Ux issue with Calva.

roelof 2020-12-10T21:15:27.390200Z

I know but calva did not even start up

roelof 2020-12-10T21:16:15.390500Z

this is my repo so far : https://github.com/RoelofWobben/Learning_in_public

roelof 2020-12-10T21:16:51.390700Z

yep, as one of the challenge was to make my own filter method

dpsutton 2020-12-10T21:17:38.391600Z

your classpath is by default "src" so requiring chapter4 will look for src/chapter4.clj but that file is located at src/ground_up/chapter4.clj

roelof 2020-12-10T21:18:08.392300Z

oke, I can do that

dpsutton 2020-12-10T21:18:30.393200Z

the namespace needs to be ground-up.chapter4 or the file can be moved out of the ground_up directory to just src or you can add src/ground_up onto your classpath and leave the namespaces alone

roelof 2020-12-10T21:18:42.393500Z

I did this because the next step in the course is the brave book and I do not want two chapter 3 in the repo

roelof 2020-12-10T21:21:19.393900Z

thanks, everything is working fine now

roelof 2020-12-10T21:28:31.394200Z

Gn , really time to sleep

💤 1