Fork me on GitHub
#beginners
<
2019-09-07
>
jayesh-bhoot05:09:52

Hi. Am I correct to claim that clojure is more about [data, its immutability, shape of data (closest term I could find is data driven design)] than about [functional programming]? And that its just FP aspects lend themselves naturally to data management?

seancorfield06:09:50

@jayesh-bhoot You'll probably get a lot of different opinions on that. I think it certainly emphasizes data-driven design but it is definitely a general purpose language. I think the immutability and the functional programming contribute to it's ability to work effectively with data.

seancorfield06:09:48

Just today I'd been looking at an enhancement request product management had requested and initially I saw it as a process change and it was hard to solve -- but then I took a step back and viewed it as a data-driven change and it became easy, specifically because of immutability and the ability to pass "modified" versions of the control data structure around without affecting other threads (and viewing functions as "data").

jayesh-bhoot07:09:32

Nice! While data orientation is integral to FP, I found that the popular lens of FP has a lot of baggage - strong typing, monads, what not. However, starting out from the shape of data and immutability, other concepts seem to fall in place around that. This was my feeling with redux. It has tons of terminologies, enough to scare a beginner away. But looking at the core of redux as - transition of shape of state/data from one snapshot to another over time - triggered by actions, rest of the concepts then simply enable/facilitate this transition. This thought process is what led me to clojure actually. Only now has it become clear. My initial journey was from the lens of FP oriented language, and led me to Haskell. That jump was stupid. But this data driven perspective seems much more malleable, and it led me to clojure. I hope my beginner's ramblings make some sense haha.

benbelly15:09:49

I’m looking for a function that filters and returns two collections - the filter “successes” in one and the “failures” in another. Easy enough to write, but seems common enough that I figure I am just missing it.

benbelly15:09:34

Dang it. Nevermind. Found it. split-with

leonoel15:09:38

group-by seems like a better fit according to your description

benbelly15:09:36

Thanks, that’s great!

matthias.schott15:09:38

What is the best way / easiest way to cycle through a list with an offset? I came up with a kinda overcomplicated solution mapping over the list with a mod calc. Curious to hear your suggestions.

matthias.schott16:09:57

Btw.: my solution looks like this:

(defn getNoteVals [notes offset]
  (for [n (range (count notes))]
    (nth notes (mod (+ offset n) (count notes)))))

leonoel16:09:17

maybe more idiomatic

(defn getNoteVals [notes offset]
  (->> (cycle notes)
       (drop offset)
       (take (count notes))))

matthias.schott16:09:49

That is what I was looking for. Thx

hoertlehner16:09:19

I have a stupid problem again. My repl used to load dependencies automatically, and now it doesn't. Is there any way how to load all clojure files into the repl?

hoertlehner16:09:03

Perhaps I also can run some function automatically on repl start? I only found docs how to set this globally, but not in project.clj

seancorfield17:09:57

@hoertlehner not quite sure what you mean -- can you give a more concrete example with details of how you have things set up?

hoertlehner17:09:00

I use leiningen. I start the repl with "lein repl". Now for whatever reason the namespaces in my project no longer get loaded.

hoertlehner17:09:20

So I want to do a very simple startup-function that gets started automatically when I run "lein repl"

delaguardo17:09:48

Clojure repl loads user namespace when starting the process. You can require all namespace that you need on start here. Just create the file user.clj somewhere inside of the root of your classpath (usually src/user.clj or dev/user.clj if you don't want to provide this file as a part of published artifact) declare namespace as (ns user (:require %your dependecies%)) and restart your repl

hoertlehner17:09:33

What could be the reason when sub-dependencies are not loaded?

hoertlehner17:09:48

When I compile to JAR it works fine.

hoertlehner17:09:04

But since today I have issues in loading my namespaces in the repl.

delaguardo17:09:15

Your namespaces or external libraries?

delaguardo17:09:39

Probably your dev classpath is not configured same way as the one used for jar building

hoertlehner17:09:50

my namespaces

hoertlehner17:09:54

but also external libraries.

delaguardo17:09:10

I can recommend to check the changes in project.clj happens since last working version

delaguardo17:09:12

But this is not a silver bullet usually. Ultimate fix - read more about how classpath is constructed by leiningen and eventually everything will be clear)

hoertlehner18:09:03

I think I have a circular dependency somewhere.

hoertlehner18:09:07

This is my best guess.

hoertlehner18:09:07

I think I figured it out.

hoertlehner18:09:09

:main ^:skip-aot job.core

hoertlehner18:09:12

this is the key setting.

hoertlehner18:09:25

all namespaces required by the file job.core

hoertlehner18:09:27

they get loaded

hoertlehner18:09:46

the ones that are not required via job.core (directly or indirectly)

hoertlehner18:09:53

they dont get loaded to the repl.

hoertlehner18:09:59

and for whatever reason

hoertlehner18:09:13

those dependencies that are not loaded dont load sub dependencies when I do it manually.

dpsutton19:09:56

that's very strange behavior. if you (require [the.ns]) it should load any of the dependencies of the.ns

hoertlehner23:09:19

Just found the problem.

hoertlehner23:09:31

nrepl via lein nrepl did not cause the issue.

hoertlehner23:09:41

I was using protorepl in atom, which internally uses nrepl

hoertlehner23:09:50

and that was not refreshing somoethinig.

mathpunk18:09:56

This might be better for #java but I feel pretty beginnery when working with it so--- I happen to have two MIDI devices, and they don't talk to each other; one is on channel 8, and the other is on 10. I figure, hey, put a computer in the middle. So now I'm trying to understand the Kingdom of javax.sound.midi Nouns...

mathpunk18:09:33

To get started, I'm trying to communicate with my sampler. For now I want to be able to read when I trigger a message with the little drum pads, because I figure, if I can read a MIDI message as data, I can figure out what to do with it

mathpunk18:09:18

(class finger-drums)
=> com.sun.media.sound.MidiInDevice

mathpunk18:09:29

Evidently you have to get a transmitter out in order to do anything

mathpunk18:09:59

(class (.getTransmitter finger-drums))
=> com.sun.media.sound.MidiInDevice$MidiInTransmitter

mathpunk18:09:05

I dunno what's up with the $ but, ok

mathpunk18:09:24

so here's where I'm stuck: I figured, there must be a way to read whatever the transmitter is sending

mathpunk18:09:10

A Transmitter has these methods: close, getReceiver, setReceiver

mathpunk18:09:35

But a Receiver doesn't seem to have a constructor?

mathpunk18:09:43

So I was hoping to construct a new Receiver, tell it that its only job is to do some kind of like, println callback when it sees a message, and set it to be the receiver of (.getTransmitter finger-drums)

mathpunk18:09:26

But if I can't construct one, I don't know how to experiment with it

mathpunk18:09:25

so I guess I have a question, "how can I get data off this transmitter", and a metaquestion, "how can I get better at learning to clojurify webs of Java objects"

mathpunk18:09:00

I'm hoping that if I put in the work to understand these interfaces then I'll have a working instrument by, oh, May 😆

seancorfield18:09:12

The $ indicates a nested class.

mathpunk18:09:20

"It is a way of logically grouping classes that are only used in one place"... fair enough, that makes sense

mathpunk18:09:58

mm, and MidiInTransmitter is not Transmitter

seancorfield19:09:53

It's a subclass I believe?

seancorfield19:09:11

On my phone -- hard to lookup docs!

mathpunk19:09:22

I am not doing great at finding the right docs! I was hoping that javadoc would direct me but I end up at a google search result with allinurl:com/sun/media/sound etc

mathpunk19:09:08

MidiInTransmitter != MidiDeviceTransmitter... this is what I meant by, I'm mired in nouns

seancorfield19:09:18

You need to create a receiver object (that will process events) and then call .setReceiver on that transmitter object to register it.

seancorfield19:09:38

The transmitter will call .send on your receiver object for each midi event

mathpunk19:09:32

https://docs.oracle.com/javase/tutorial/sound/MIDI-messages.html seeeems to suggest, the way to get a receiver from a MidiDevice

mathpunk19:09:22

but a receiver that is not associated with a device -- it's just something to examine MIDI events to learn what's in them... dunno if that's possible

mathpunk19:09:10

(I'm just trying to avoid having to understand two devices at once, since I barely know what's happening here)

seancorfield19:09:55

I don't have any midi devices to test this with, but in Clojure you will reify javax.sound.midi.Receiver and implement the close and send methods.

seancorfield19:09:27

Attach that reified object as a receiver on the transmitter you got from your midi device.

seancorfield19:09:01

Something like

(.. device getTransmitter (setReceiver (reify javax.sound.midi.Receiver (close [this]) (send [this message stamp] ... (.getMessage message) ...))))
untested, off the top of my head.

mathpunk19:09:46

"something like" is way better than what I had... thanks Sean, will report back after some fiddlin' (so to speak)

seancorfield19:09:15

.getMessage returns a byte array, FYI.

mathpunk19:09:51

I have hit the drum pad and gotten.... some junk I don't understand!

mathpunk19:09:00

time to learn about byte arrays 🙂

seancorfield19:09:25

Yay! Midi event unlocked! 🙂