Fork me on GitHub
#off-topic
<
2019-07-25
>
jjttjj04:07:47

I'm wrapping a library for stock market data. I can request time series and it gives me back strings with just the date, in a timezone that is set via configuration. As a library, is it best to turn these into LocalDateTimes, ZonedDateTimes or Instants? I'm currently using ZonedDateTime time because in practice it seems like I usually want to work at this level. But I could also see an argument for the LDT (technically that's all that is provided in the string, and I could leave it up to the user to construct the ZDT) or the Instant (seems a bit more standard I guess? if so, is a clojure #inst better than java.time.Instant?). What's your pick here?

seancorfield04:07:35

@jjttjj My preference is to work in UTC in the core and convert from/to TZ at the edges when displaying or getting input.

seancorfield04:07:07

We have all our servers set to UTC, and our JVMs, and our databases. Then we display in local times based on TZ.

👍 20
jjttjj05:07:00

@seancorfield thanks! Do you tend to default to java.time.Instants or one of the clojure inst types?

seancorfield05:07:00

We're slowly shifting to Java Time.

seancorfield05:07:48

But it's complicated. We have a mix of java.util.Date and date-clj as well as Joda Time and clj-time but we're moving to Java Time (and clojure.java-time where it makes things clearer).

jjttjj05:07:36

ok good to know thanks

alexmiller05:07:38

#inst is not a type, it's a means to print/read instant values

alexmiller05:07:11

so #inst vs java.time.Instant is a false comparison

alexmiller05:07:38

anything being written in modern times should use java.time.Instant imo

Kanister09:07:27

check this out: https://flow.org/en/docs/config/#toc-comments how flow does commenting 😂

💩 4
bherrmann11:07:39

Wow, cognitect only has 28 people. https://cognitect.com/about.html

borkdude11:07:20

a testament to the power of Clojure: do more with less people 😉

👍 8
borkdude12:07:26

btw, I bet those 28 people doesn't include the pool of contractors/freelancers they do projects with under the name Cognitect, which might be a lot more?

Daniel Hines14:07:06

Halp! My company asked me to write a proposal to the RVA JS conference in Richmond. I’ve never done a conference talk, and I have no idea what they’re looking for as far as a proposal. Any advice? I have a topic: integrating the logic programming language ASP into React/Redux applications. I just have no idea what would turn that into a winning proposal.

alexmiller14:07:23

a simplified hero's journey approach is often useful - 1) you face a problem 2) you try X and it doesn't work, 3) you do Y and it saves the day

😁 8
👍 12
eggsyntax15:07:29

I usually find it helpful to include 2.5, atonement with the abyss.

😂 12
eggsyntax15:07:22

Although sometimes you don't have time for both atonement with the abyss and a Q&A section, so 🤷

alexmiller15:07:50

well I'd pick atonement over Q&A :)

👍 4
Daniel Hines19:07:02

Functional programming is experientially simpler, which I usually associate with “pulling things apart”. What things does FP pull apart?

jaihindhreddy19:07:56

Immutability (or the illusion of it), which is a critical part of FP (in my mind) pull apart identity and value. But IMHO, Immutability doesn't pull apart anything, they are already apart, OO complects them.

Daniel Hines19:07:56

In a recursive function, a var can change values with each iteration.

Daniel Hines19:07:34

Recursion can simulate state, at which point you can encounter many of the same problems as imperative languages.

Daniel Hines19:07:41

The more I think about it, closure is a very, very strange property. The Eve guys found it was the hardest thing for non-programmers to understand, and I see why.

4
jaihindhreddy19:07:47

If it's referentially transparent, then that's just implementation detail. Just like when into uses transients

jaihindhreddy19:07:04

Also, we can pull out a value from a Clojure var anytime we want. Which we can't in a mutable object without stopping the world from interacting with it (locking)

Daniel Hines19:07:43

If I pass as a hashmap in as the first argument to every function in my program and reference it, I’ve essentially simulated a global var.

Daniel Hines19:07:47

If I pass as a hashmap in as the first argument to every function in my program and reference it, I’ve essentially simulated a global var.

Daniel Hines19:07:12

I’m not really considering concurrency at the moment.

4
Daniel Hines19:07:33

(People argue for FP in single-threaded environments to achieve simplicity as well)

jaihindhreddy19:07:52

In terms of the reasoning power about a construct (a fn, a method etc), the things that affect that are the ones that can affect the way the construct behaves. For a mutable object with hidden state, it is the args passed to the constructor, and all method calls ever done on the object, whereas for a function, it's just the args. That still means we need to understand and think about the args. If the args are "the entire world", then we have to understand a value of the entire world to understand the function.

👍 4
jaihindhreddy19:07:18

Sorry for the noise. Am unable to articulate it any better 😅

Daniel Hines19:07:09

No - that’s actually a great way of parsing it. Thanks!

😅 4
jaihindhreddy19:07:36

Just trying to climb the shoulders of giants, who are on top of other giants. (It's giants all the way up!) Speaking of "Are we there yet" by Rich Hickey and "Process and Reality"

andy.fingerhut19:07:27

Yeah, pure FP makes "the entire world" you must consider limited to the args, and any non-args you read in the function body, which effectively become hidden/implicit args. "the entire world" gets much messier to think and reason about with mutability, especially in C/C++/Java where by default things are mutable, and it is common practice to mutate them wherever you wish.

andy.fingerhut19:07:05

Even in pure FP systems, I have heard in Om/reagent/etc. systems (which I've never used, so take my comments with a grain of salt unless someone experienced in using them confirms this) that passing around a big nested map adds cognitive load, hence a common technique is to take subsets of that big map and pass only what a particular function cares about.

seancorfield20:07:08

Back in the day... I developed a system that analyzed C source code and translated it to MALPAS which is used for program proving through transformation (used by the UK defense industry and others). MALPAS has limited side-effects and no globals. The translator had to analyze the complete C program and figure out all the globals and turn them into a single (mutable!) data structure that was created in the MALPAS main and then passed through every single function call as an argument. It really brought home how much additional complexity global variables add to code!

seancorfield20:07:52

In fact I think we actually had to pass them as separate arguments and mark them IN/OUT/INOUT on every call? Memory's a bit hazy as this was in the 80's.

andy.fingerhut21:07:09

I have attempted to be slightly humorous before by pointing out that as soon as you go outside a small subset of C, there is basically one data type: array of byte from 0 up to virtual memory max-1.

andy.fingerhut21:07:11

And I am pretty sure that 99% of the C code I have ever written actually relies upon assumptions I was making about the particular combination of C compiler, command line options, and processor that was being targeted.

seancorfield21:07:10

Another product I worked on back then could tell you for sure @U0CMVHBL2 🙂

seancorfield21:07:37

It was a C compiler and runtime that identified every single occurrence of unspecified, undefined, and implementation-defined behavior in your code. I was going to link to the product page but it looks like the company that licensed it has resold it recently (to Perforce) and the original MISRA analysis engine is no longer available...