Fork me on GitHub
#clojure
<
2016-08-29
>
seylerius01:08:04

Given a seq that contains vectors and strings, arranged as 0-2 vectors, 1+ strings, 0-1 vectors: how do you most efficiently consolidate the strings in the middle?

seylerius01:08:43

Two examples: [[:foo] [:bar] "T" "h" "i" "s" " " "S" "e" "c" "t" "i" "o" "n" [:tags]] ➡️ [[:foo] [:bar] "This Section" [:tags]] ["This Section"] ➡️ ["This Section"]

gfredericks01:08:05

(->> thing (drop-while (complement string?)) (take-while string?))

seylerius02:08:06

@gfredericks: That looks like an excellent way to get just the strings. Apply str to that and I'm golden.

seylerius02:08:49

Okay, got another one. Given a nested tree of seqs, where some seqs start with a keyword and others with a string: how does one pop open any seqs that start with a string?

seylerius02:08:27

Example:

([:title "Sample Org File"] [:author "Seylerius"] ("This is an attempt to test Org-Mode processing." [:section [:h [:stars "*"] [:keyword "TODO"] [:priority "A"] "T" "h" "e" " " "*" "F" "i" "r" "s" "t" "*" " " ":" " " "S" "e" "c" "t" "i" "o" "n" [:tags "foo" "bar"]] "This *is* /the/ _content_ +oof+ of the first section. There's also a list. " "+ First UL" "+ Second UL" "+ Third UL" ""] [:section [:h [:stars "**"] "The First SubSection"] "This subsection contains a nested list." "1. The first OL" "+ UL 1.1" "+ UL 1.2" "2. The second OL" "+ UL 2.1" "+ UL 2.2" "3. The third OL" "+ UL 3.1" "+ UL 3.2"] [:section [:h [:stars "**"] "The Second SubSection"] "1. OL 1 of List 1" "2. OL 2 of List 1" "There are two lists in this subsection" "1. OL 1 of List 2" "2. OL 2 of List 2" ""] [:section [:h [:stars "**"] "The Third SubSection"] "This subsection has a table." "| Name | Value |" "|------+-------|" "| One  | Foo   |" "| Two  | Bar   |"] [:section [:h [:stars "**"] "The Fourth SubSection"] "This subsection has a definition list." "+ Foo :: Foo" "+ Bar :: Bar" ""] [:section [:h [:stars "*"] "The Final Section"] "Thus ends the sample." ""]))
➡️
([:title "Sample Org File"] [:author "Seylerius"] "This is an attempt to test Org-Mode processing." [:section [:h [:stars "*"] [:keyword "TODO"] [:priority "A"] "T" "h" "e" " " "*" "F" "i" "r" "s" "t" "*" " " ":" " " "S" "e" "c" "t" "i" "o" "n" [:tags "foo" "bar"]] "This *is* /the/ _content_ +oof+ of the first section. There's also a list. " "+ First UL" "+ Second UL" "+ Third UL" ""] [:section [:h [:stars "**"] "The First SubSection"] "This subsection contains a nested list." "1. The first OL" "+ UL 1.1" "+ UL 1.2" "2. The second OL" "+ UL 2.1" "+ UL 2.2" "3. The third OL" "+ UL 3.1" "+ UL 3.2"] [:section [:h [:stars "**"] "The Second SubSection"] "1. OL 1 of List 1" "2. OL 2 of List 1" "There are two lists in this subsection" "1. OL 1 of List 2" "2. OL 2 of List 2" ""] [:section [:h [:stars "**"] "The Third SubSection"] "This subsection has a table." "| Name | Value |" "|------+-------|" "| One  | Foo   |" "| Two  | Bar   |"] [:section [:h [:stars "**"] "The Fourth SubSection"] "This subsection has a definition list." "+ Foo :: Foo" "+ Bar :: Bar" ""] [:section [:h [:stars "*"] "The Final Section"] "Thus ends the sample." ""])

seylerius02:08:57

Maybe something with walk, but I'm not sure how to break the seq apart after I've identified one.

dpsutton02:08:34

to break apart a string just (map str (seq s))

seylerius02:08:17

@dpsutton: Not quite what I'm aiming at. I need to break apart seqs that start with strings into their individual items as part of the parent seq.

seylerius02:08:34

[[:foo "a"] [:bar] ("baz" "bar" [:foo "b"])] ➡️ [[:foo "a"] [:bar] "baz" "bar" [:foo "b"]]

seylerius02:08:21

As far down as necessary to return the tree to be hiccup compliant.

dpsutton02:08:37

i don't think hiccup cares about the sequences actually

dpsutton02:08:40

have you rendered them?

seylerius02:08:40

Inataparse flails and says it's not compliant if I try to use insta/transform without popping the non-compliant seq.

seylerius02:08:16

Basically, given a seq, how do you return its contents unwrapped?

dpsutton02:08:23

this doesn't recurse on the lists though, so not sure if you'll have lists inside of lists, etc

seylerius02:08:04

@dpsutton: Actually, this gives me an idea. Thanks, this is very nearly what I need.

dpsutton03:08:51

@seylerius that should recurse on each list

dpsutton03:08:02

and assumes vectors are not to be modified at all

seylerius03:08:30

Trouble is vectors might contain lists sometimes.

seylerius03:08:10

Going to hit it with a pass off fixing the tree after each thing that might add a new list. Think I've got it...

dpsutton03:08:08

just reduce each vector

dpsutton03:08:22

a vector can contain that stuff because that case is identical to the one we started with

dpsutton03:08:26

ie, recurse

meta-meta03:08:52

@lmergen I'm trying to build a model of music theory for music generation and analysis. I thought it would be helpful to have a circular list to define the concept of pitch classes. Something like (def pitch-classes (cycle [:c :db :d :e :eb :f :f# :g :ab :a :b])) although I suppose cycle is only infinite in one direction and I'll need to go both ways but you get the idea. I figure it will be useful to say (take n pitch-classes) then filter/map over them to generate chord progressions. I know I can come up with other ways to do this but half of this project is about learning clojure with the goal of representing musical contexts as directly as possible. I could just be more careful but it sucks worrying that you'll crash the REPL especially if I plan to use this for live performance down the road.

seylerius03:08:21

Damnit, the list in this isn't passing list?.

dpsutton03:08:10

what do you mean

seylerius03:08:58

If I filter with list?, I get an empty seq.

dpsutton03:08:13

did you try my snippet above on it?

dpsutton03:08:30

what are you filtering?

seylerius03:08:22

The sample data I listed.

dpsutton03:08:39

ah. yeah. don't think filter can get rid of lists

seylerius03:08:06

What's annoying is that this function is failing. It seems to be because the list in the middle of the list is not passing the list? test.

(defn tree-reducer
  [tree item]
  (if (list? item)
    (concat tree item)
    (conj tree item)))

seylerius03:08:29

Yours didn't pop the list either.

seylerius03:08:26

Gah. I'll just search on collections that aren't vectors.

dpsutton03:08:56

i thought mine does "pop" the list

dpsutton03:08:15

in your example, we can't just concat the item, we need to check for nested sublists

dpsutton03:08:58

so we concat and then reduce inside of the list, each element of it, looking for vectors, other lists, strings, etc

seylerius03:08:03

There we go. I modified yours to check for (and (coll? e) (not (vector? e)), and that fixed it.

seylerius03:08:27

The list didn't accept its list-ness.

dpsutton03:08:28

which collection was messing it up? a sequence?

seylerius03:08:42

Yeah. Must've been a generic seq.

dpsutton03:08:50

oh well. you're set then?

seylerius03:08:27

Yep. I'll put this in as my tree fixer, and run that between parsers.

seylerius03:08:31

Thanks, dude.

dpsutton03:08:37

awesome. best of luck

hans11:08:39

I have a faint recollection that I read discussions about the new version of clojure.data.xml in this channel. Is anyone here involved in the refactoring effort?

dpsutton12:08:40

Is there any way to call the java bit shifting operators? I'm not too familiar with java and was hoping that the operators << etc had functions behind them that I could call

dpsutton12:08:57

and in case its an x,y problem, I'm trying to get the most significant bits from an integer

robert-stuttaford12:08:37

(defn mask-partition-from-tempid [tempid]
  (bit-or tempid 0x7FFFFFFF00000000))

dpsutton12:08:38

I built up a lazy list of bit-masks of 1's from the least significant bit, and then shift right and and it with the correct bit mask. Trouble is sometimes my integers get promoted to longs, so i was wondering if there was a way to reach out and do it in java so i knew there would be no type promotion

sveri14:08:55

Hi, using luminus / compojure, how do I redirect and update the session?

sveri14:08:26

ok, its (assoc (redirect "/") :session :session)

fenton15:08:48

how to achieve the following: {:a [1 2]} [3 4] -> {:a [1 2 3 4]}. That is i have a map with a key that holds a list and and more of the list that I want to conj onto it.

dpsutton15:08:57

(update-in m [:a] conj [3 4])

yonatanel15:08:22

concat instead of conj i think

dpsutton15:08:56

(update-in {:a [1 2]} [:a] (comp vec concat) [3 4])

dpsutton15:08:01

to watch the vector return type

dpsutton15:08:06

i always forget the seq return

dpsutton15:08:01

no problem fenton. happy coding

yonatanel15:08:03

actually, into is enough

(update-in m [:a] into [3 4])

fenton15:08:25

thnk god its clojure! 🙂

dpsutton15:08:48

ah very nice

radon15:08:18

(update {:a [1 2]} :a into [3 4])

radon15:08:53

Note that update is new in 1.8, so you can’t use it in older versions.

fenton15:08:21

k...clojure code almost makes me cry for a wasted 15 years of my life!

dpsutton15:08:26

fenton, it's okay to like vb5

fenton15:08:22

is there a more elegant way to achieve: (def mm {:long-keyword 1 :b 2}) -> [:long-keyword (:long-keyword mm)]-> [:long-keyword 1]

radon15:08:50

((juxt identity mm) :long-keyword)

fenton15:08:50

@radon will go read about that now! never used juxt before.

radon15:08:37

Also great for getting the minimum and maximum of a collection at the same time:

(apply (juxt min max) [7 4 3 0 19]) => [0 19]

fenton15:08:46

@radon that is really neat...

yonatanel18:08:18

@fenton: select-keys might also help you with similar problems.

(select-keys {:a 1 :b 2} [:a])
=> {:a 1}
(first (select-keys {:a 1 :b 2} [:a]))
=> [:a 1]

machty18:08:17

noob question: is there such thing as an "opaque" type in clojure? by that i mean an record/object/hash whose values can't be read/fetched by anyone other than the namespace that created / knows how to manage that object?

machty18:08:32

kinda like encapsulation/private fields in OOP

machty18:08:49

or is everything just a hash/map/set/vector that everyone can operate on?

jswart18:08:25

Yes, mostly. This is usually less of a concern because the data is immutable. So even though everyone can operate on it, they can’t change it.

jswart18:08:42

But I’m not sure what your specific use case is, and maybe someone else will have a better answer.

machty18:08:35

i still mostly work out of a ruby codebase and find that a lot of the design decisions i make are to effectively hide/privatize as much of the data accessors as possible so that future developers are steered in the right direction

machty18:08:58

i bet someone would read what i just wrote and wonder if there isn't some accidental complecting happening since we're using OOP, but...

machty18:08:27

do clojure developers run into situations where since the data is lying out in the open (no private fields, encapsulation) that the next developer adding a feature to a large project starts digging into the internals of some data structure rather than adhering to a design meticulously laid out by a previous developer?

machty18:08:37

i hope i'm making sense...

jswart18:08:14

Hmm, that is a broad question. In my experience most CLJ devs prefer things to be open so they can be built upon rather than wrestled with.

jswart18:08:42

As in: having a few well thought out abstractions and generic data types that anyone can operate on with existing functions.

jswart18:08:00

Most data is a map, than can be managed as the user not the implementor sees fit.

machty18:08:30

interesting

machty18:08:39

someday i'll get my hands dirty w clojure

jswart18:08:21

again I’m just one dude

jswart18:08:30

others might really disagree or do it differently

exupero18:08:41

@machty A lot of that kind of data hiding happens in function closures.

exupero18:08:37

Data structures don’t often need state; it’s functions that need state when they operate on data structures.

fellshard19:08:00

I believe - from what I've seen of Hickey's philosophy and how it's extended into Clojure - the data is central; the model is exposed so that other functions can act on it clearly. It also fits in with the feedback loops and rapid incremental development cycles of a REPL, as well as the benefits of referential transparency. All the needs for privatization of data tend to disappear when you're not worrying about shared or global state.

fellshard19:08:40

I think that was the theme of one of his keystone talks, I'd have to dig it up again though...

fellshard19:08:28

I think it was either 'Are We There Yet?' or 'The Value of Values', both of which can be found from https://changelog.com/rich-hickeys-greatest-hits/

fellshard19:08:43

You tend to spend more time coming up with the right state and data representation in Clojure than you do coming up with the right interface.

machty19:08:24

i don't think all the needs for privatization disappear. i understand how they do when mutability is out of the question, but still whether you're using OOP or a functional style, you are building dependencies in your code; if you have any sort of top level state, or any kind of object composed of other objects that gets passed around, then anyone can dig in and read any values from that object and make decisions based on their understand of the present-day shape of that object

fellshard19:08:39

Function-level scoping. 😉

fellshard19:08:52

You don't blindly leave global values lying around, for sure.

fellshard19:08:24

In Clojure, dependencies are often simply what's passed into a function.

machty19:08:25

i guess specifically if you have some deeply nested map that uses :mykey and then it's changed to :newkey, then anyone who might have been digging into that structure from another side of the program will have to be updated or be broken

fellshard19:08:51

Yep. Hence the time spent making sure that state is well-selected.

machty19:08:15

hence my question about opaque types: it seems like it'd be nice to still have a single namespace that knows how to operate on a proprietary data structure, but to everyone else the data is opaque and you're forced to use the functions exposed by that namespace

fellshard19:08:18

The same would happen if you changed a method signature in OOP; just takes some getting used to those breaking changes occurring along a different medium.

machty19:08:39

methods are less brittle than internal state; that's kind of the point of them

machty19:08:58

(also to control/limit where mutation happens, but even with out that concern there are design/dependency considerations)

fellshard19:08:16

There is no mutation in Clojure unless explicitly stated. 🙂

machty19:08:30

yes i am quite aware 🙂

machty19:08:42

there's still the issue of limiting dependencies between code

fellshard19:08:11

I think it's more in line with OOP than you may think. Think of it from a module integration perspective.

fellshard19:08:45

In general, while it may be function endpoints that bind two modules together, they generally negotiate that exchange through a common medium of data.

fellshard19:08:13

They share some model that defines the shape of how both modules can see their slice of the world in common.

fellshard19:08:34

You can encapsulate that, yes, but if the model changes both sides change with it.

fellshard19:08:23

The same problem exists, it's just along a differently shaped seam.

machty19:08:51

i've been using data as a boundary between modules in my ruby projects lately to great effect, but even still, the blob passed between modules can benefit from opaqueness and only exposing a set of functions (methods) that know how to interact with it. And I believe that's actually a place where records/protocols could fit in nicely, but it still seems strange to me that there's no way to prevent someone from bypassing the utility record "methods" and just grab at the internals

fellshard19:08:10

Give it some time. Consider it from the perspective of "I'll provide a set of tools to make interaction easier, but you can create your own custom tools at your own risk." It's extensibility a la carte, really.

fellshard19:08:24

This talk in particular helped shape my mindset a bit in how Clojure can be used: https://www.youtube.com/watch?v=ShEez0JkOFw

fellshard19:08:24

Kind of an oddball of a talk, but the concept of crafting simple tools that perform flexible tasks for your particular needs resonated well.

fellshard19:08:34

Seems that most of your concern is around how a data model evolves over time, which is a challenge in all paradigms (I suppose that makes it an orthogonal problem...)

fellshard19:08:09

So it's mostly a matter of figuring out how to combat that in Clojure. That I have less experience in; anyone able to chime in with their experience there?

val_waeselynck20:08:42

@machty if you need an indirection between data representation and data querying protocols or multimethods are a great fit :)

val_waeselynck20:08:20

the point is just that this indirection should not be the default; one of thd key aspects of programming with values is that values are explicit.

unknown-unit20:08:01

From my perspective, declaring something private in a map of data returned by (or passed in to) a function makes no sense. I can’t think of a reason I’d want to. If I want something not accessible in the map, I don’t add it to the map. I’m passing around data (to which I want the external code to have access) and functions, not objects containing data and functions. You can declare things private in a namespace. I do it all the time, but more with the intention of defining the public interface than preventing direct access. Functions inside a map which access private data in their namespace aren’t exposing that data. They control the access just as in OOP. I don’t see how this differs significantly from the OOP model. You still have well defined public functions which control how external code interfaces with the namespace and uses its private data. Any change to the public interface has the same consequences in both paradigms. It might help if instead of thinking about passing objects around, you thought about being able to send just the public data and functions from the object instead of having to send the entire object. These functions still have access to the internal state, it just doesn’t come along with them.

fellshard20:08:17

Private data within a namespace is more like pure ambient context at that point.

ag21:08:07

does anyone know when can we expect to see clojure.spec functions in http://clojuredocs.org?

bostonaholic21:08:26

@ag maybe when 1.9.0 is released?

ag21:08:52

oh cool, thanks. I can’t wait for when it’s out and people add awesome examples on http://clojuredocs.org. It’s hard to learn straight from docstrings.

bostonaholic21:08:16

there are some good videos on the cognitect blog

dpsutton22:08:41

so here's a strange one. I'm using clojure.java.jdbc to access microsoft sql server. I'm using a dependency on com.microsoft/jdbc4 "3.0" on windows and fedora 24. We were running the the webserver on ubuntu 14.04 and recently upgraded to ubuntu 16.04. Now I'm getting the error that java.sql.SQLException: No suitable driver found for jdbc:sqlserver://<valid-connection-string>

dpsutton22:08:00

anyone have any experience wrestling with the database driver across all of this?

dpsutton22:08:29

on the machine we were limited to java 1.7, but after upgrading to 16.04 we upgraded to java 1.8

gfredericks23:08:32

so I really want to turn stuartsierra's how-to-ns into a library/lein-plugin that can lint code and fix up namespace forms

gfredericks23:08:20

but I was wondering if there was some other existing thing that I should try to build on rather than making a standalone thing

gfredericks23:08:27

e.g., eastwood, cljfmt

gfredericks23:08:56

slamhound breaks most of the projects I work on, though, so I'd have to figure out why that is before it'd be useful :/

bostonaholic23:08:27

I wonder why that would be

gfredericks23:08:52

lots of edge cases; e.g. I think if you import a class just to use it in metadata, it thinks it's unused

gfredericks23:08:05

if you require a namespace for side effects, it probably removes that too

bostonaholic23:08:28

that’s probably telling you something then!

gfredericks23:08:36

well until multimethods are designed differently, requiring a namespace for side effects might be a reasonable thing to do

Drew Verlee23:08:59

i’m having a moment here, how does using something like clojure spec compare to using something like like thrift or protocal buffers. One obvious difference is that those are concerned about encoding & decoding, where spec is only interested in validation (right?). In that same vein i suppose spec seems similar to json-schema but is more powerful, because it can be used for data generation (property testing). Reading http://shop.oreilly.com/product/0636920032175.do chapter 4 on Encoding and evolution.

Drew Verlee23:08:43

is something like https://github.com/plumatic/schema strictly more powerful then something like https://github.com/metosin/scjsv? Or i’m i comparing apples to oranges?