This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-07-05
Channels
- # bangalore-clj (1)
- # beginners (50)
- # boot (72)
- # cider (53)
- # cljs-dev (303)
- # cljsrn (2)
- # clojure (403)
- # clojure-conj (3)
- # clojure-dev (7)
- # clojure-italy (18)
- # clojure-russia (129)
- # clojure-sg (1)
- # clojure-spec (44)
- # clojure-uk (25)
- # clojurescript (112)
- # core-async (4)
- # core-typed (3)
- # cursive (23)
- # datomic (114)
- # defnpodcast (1)
- # emacs (1)
- # figwheel (2)
- # graphql (18)
- # hoplon (110)
- # instaparse (6)
- # jobs (3)
- # jobs-discuss (10)
- # leiningen (5)
- # luminus (1)
- # lumo (151)
- # off-topic (22)
- # om (3)
- # om-next (3)
- # onyx (4)
- # parinfer (1)
- # pedestal (8)
- # precept (51)
- # re-frame (19)
- # reagent (3)
- # ring (1)
- # ring-swagger (5)
- # spacemacs (21)
- # sql (25)
- # test-check (2)
- # uncomplicate (8)
- # unrepl (33)
- # untangled (20)
- # yada (14)
I like how the problems on 4clojure are 2x harder then any i have solved in my professional career so far… This one is a puzzler. I keep getting close but then their is some flaw to my plan. Like, the problem is handling the numbers that dont fit. Its easy to keep the full structure by filtering out the bad ones, but the answer doesn’t have the same structure of collections. Or its easy to stop at the last number that doesn’t fit, but then i can’t construct a function that doesn’t return nil for that number and muck up the whole thing. http://www.4clojure.com/problem/112
oh yeah, horribilus is right
that one took me a long time (I stopped doing 4clojure for a while when I hit it, came back and approached it totally differently later)
@vinai I sometimes use spyscope for this especially when debugging. Specifically the #spy/p
reader tag is the one that pretty-prints the form that follows. https://github.com/dgrnbrg/spyscope
I think one thing that makes the puzzle particularly hard to solve in clojure is that its logic doesn't really respect the structure of the data, which makes us deal with the input in ways that are "weird" compared to our usual facility with data transforms
like, a deeper element might cause us to erase elements that are higher, or a higher element might make us remove ones that are deeper... it doesn't really fit our usual patterns very well
@noisesmith thanks for the perspective!
drewverlee: thanks for reminding me of this problem, it’s a hard one. I ended up deciding I didn’t like my old answer (using an atom for a counter) and I replaced it with what turned out to be: a hand rolled monad pairing a subseq or element with a number representing remaining capacity
it doesn’t work with laziness though… I think I might need to turn to something like reify to make that work
Hmm yes I also went for an atom, I'll have to take a look at your solution when I finally get something to work
> http://www.4clojure.com/problem/112 it looks like I solved it, but pretty hacky, using keywords for returning multiple results
Seems like something that might be suited to zippers... no idea if they work on infinite sequence
Oh, I didn't read the sum
part, I thought it was a nested filter. Not sure if zippers can be told to "remove everything else" I suspect not in a way that's safe lazily, so probably not good.
modern-cljs related boot question. Unclear whether to post a bug to the github project, ask here in #beginners, or ask in #boot.
in tutorial 16 there’s a note that says, basically, if you do a (merge-env! :source-paths dirs)
where dirs
contains nonexistent paths, that there should be no error.
https://github.com/magomimmo/modern-cljs/blob/master/doc/second-edition/tutorial-16.md#update-buildboot
but I’m getting an exception “Exception in thread “Thread-18" java.nio.file.NoSuchFileException: test/clj” where the path test/clj
does not exist… ?
nevermind - I just opened a ticket in modern-cljs (https://github.com/magomimmo/modern-cljs/issues/429)
@gonewest818 I’ll take care of it in a couple of days. Thanks.
ever had a test inside a with-test
, mysteriously ignored by leiningen even when *load-tests*
is true
?
Super nooby question, but what are the pros and cons of accessing your data only through functions you define?
(defn make-person [f-name l-name] {:first-name f-name :last-name})
(def drew (make-person "drew" "verlee"))
Now say i want to access my first name. I could do this:
(:first-name drew)
which is direct but relies i know about the structure of drew. Or i could build a function that does that.
(defn get-first-name [person] (:first-name person)
and then access it using this getter…
(get-first-name drew) ;;=> drew
The way i see it, the later is more flexible as it lets you change the structure of the data containing the name. The downside is that you have to build lots of getters, which generally leaves me feeling lke i’m doing something wrong. Possible this is because setters
are the real code smell but my mind associates them together.
this also prevents things like get-in
unless get-in also knows about the structure of course
@drewverlee I think you've summed up the pros and cons alright.
also note that most of the things that make clojure great depend on not using accessors
@drewverlee unlike Java, you're not forced to have a getter for everything under the sun
great question @drewverlee -- what @noisesmith says about get-in
applies to the rest of the standard library too
@ghadi I might be some of the context from what your saying around 4:01. I wasn’t suggesting building a new type. Just making it so that access to the object went through a user defined functions rather then relying on functions that were Data structure specific. I dont see how this would effect the rest of the program.
(map get-first-name [person-a person-b])
vs (map :first-name [person-a person-b])
However even as as i write this i feel like the trade off in creating accessor is greater then i originally thought. I mean [person-a person-b]
is data, should i make an api for that? Where would it end?
So are we suggesting that its worth breaking your code if the data has to change.
{:first-name drew :last-name verlee}
-> {:names {:first drew :middle alan :last verlee}}
which would mean i have to change every place is access the first name via a keyword. e.g (:first-name person
)
In order to avoid the overhead of creating accessors? In essence keep the data as generic as possible so we can re-use as much of clojure core as possible?
if you make an accessor like get-first-name
that does something non-obvious with its argument (like assembling/computing a value, etc.) then anything else in the program needs to call that accessor instead of looking at the (immutable) data
but i think it's rare. most accessors in java end up exposing object innards as information
@ghadi so in general, you would recommend accessing data using data? e.g
({:3 "3"} "3") => "3"
([0 1 2 3 4] 3) => 3
(#{1 2 3} 3) => 3
I think it would be more accurate to say the real reason is that since (in clojure) data is immutable, there's no need for a getter.