Fork me on GitHub
#clojure
<
2016-04-05
>
crocket00:04:35

Why do VMs dominate the world now?

crocket00:04:44

Because it frees us from hardwares and operating systems?

crocket00:04:33

I'd complement C with Rust.

crocket00:04:07

Clojure is not quite like C because it is optionally typed.

crocket00:04:56

I'd like to see a clojure derivative with mandatory static typing.

adamkowalski00:04:42

how would you use transducers in a statically typed language?

crocket00:04:23

I don't immediately see a reason that I can't use it well in a statically typed language. I'd impose typeclass constraints on types rather than fully instantiate types.

crocket00:04:42

constrained polymorphism is quite flexible yet reliable.

adamkowalski00:04:39

idk, it seems like it would be really difficult to do it correctly, I think that something like core.typed has the potential to be really good and provide typing for those who want it

crocket00:04:10

@adamkowalski: Do you know typeclass?

adamkowalski00:04:31

yeah I have used them in Haskell and they are fantastic

seancorfield00:04:38

core.typed has a very long way to go before it’s comparable to any strong type system with inference.

crocket00:04:02

Does core.typed support constrained polymorphism?

adamkowalski00:04:03

but in c++ we only have templates

adamkowalski00:04:25

not sure about c because I never really need to use it

seancorfield00:04:39

C is weakly typed (at best).

adamkowalski00:04:57

I think that the extensibility of a lisp means that it is a great candidate for extension

adamkowalski00:04:07

its one of the things that draws me the most towards clojure

adamkowalski00:04:21

im almost every other language I find I lack something and I am not able to do anything about it.

adamkowalski00:04:58

in clojure if something you want doesn't exist it is possible to use macros to transform your code

crocket01:04:54

C is weakly and statically typed.

hans04:04:33

c is strongly statically typed, but its automatic casting may suggest otherwise.

seancorfield04:04:51

C is pretty much the poster child for a weakly statically typed language @hans

seancorfield04:04:17

(I developed one of the very first ANSI-validated C compiler / runtime systems, BTW)

hans04:04:30

I think we can agree to disagree.

crocket04:04:37

Compared to clojure, C's type is weaker.

crocket04:04:06

Anyway, WebAssembly will probably obsolete ClojureScript by 2020 because WebAssembly might become a legitimate compilation target for Clojure.

crocket04:04:54

Type casting and pointer arithmetic make type system weak. Union types make it weaker. Those features make it hard to enforce type constraints.

seancorfield04:04:44

I think we can agree to agree @crocket 😸

crocket04:04:07

Do you look forward to compilation of clojure into WebAssembly, too?

seancorfield04:04:28

Haven't had a chance to look at WebAssembly yet. I was agreeing with your comments about C.

crocket04:04:54

WebAssembly is basically abstract syntax tree in binary format on web browsers.

crocket04:04:16

It will become a compilation target for javascript and various web browser languages.

crocket04:04:48

WebAssembly grew out of asm.js

seancorfield04:04:36

How widely supported is it in browsers today?

crocket04:04:56

Major web browser vendors started implementing it since June 2015. Webkit, Chrome, Edge, and Firefox

crocket04:04:59

Initially, C/C++ will compile to WebAssembly, and virtual machine support will come later.

crocket04:04:30

Clojure might replace ClojureScript in the future when WebAssembly is mature and runs on a proper VM platform.

crocket04:04:46

Do you think ClojureScript will be still relevant?

arrdem04:04:03

CLJS will be relevant for a long time to come.

crocket04:04:26

The presence of WebAssembly means compilation into javascript won't be needed.

crocket04:04:38

Clojure will be a peer to javascript on web browsers.

crocket04:04:43

Major server-side javascript runtime environments like V8 will support WebAssembly, too.

arrdem04:04:42

IMO this entire comment thread applies https://lobste.rs/c/fjbmp7

arrdem04:04:30

It's fine to say that WebAssembly may come to complement JS at some point in the future, but the reality is that Clojure and ClojureScript are both designed to assume very very good garbage collectors and a very rich virtual machine/target compared to raw assembly. The day may well come when something Clojure-like compiles to "native", I just think you're grossly underestimating the amount of work required to do it, and overstating the value given the immense strengths of existing platforms.

crocket04:04:32

Your comment is about core.typed

arrdem04:04:46

No, read the linked, -1 karma autofolded thread at the bottom.

crocket04:04:25

@arrdem: WebAssembly will run on a proper VM in the near future.

crocket04:04:32

It'll expose VM semantics like garbage collection and type system.

crocket04:04:00

Meh, http://lobste.rs is becoming overwhelmed by negative-vote trolls.

crocket04:04:23

Totally reasonable comments are downvoted.

crocket05:04:27

Clojure will be able to compile to WebAssembly in the near future.

crocket05:04:31

within 10 years.

ronaldsuwandi08:04:30

Is there a way to measure the performance of map functions without realizing it?

(defn expensive [records]
  (let [result (time (doall (map inc records)))
        result (time (doall (map dec result)))]
    nil))

(defn expensive-2 [records]
  (let [result (map inc records)
        result (map dec result)]
    (doall result)
    nil))
Obviously (time expensive (range 1e6)) is faster than (time expensive-2 (range 1e6)) but the downside of the first call is that you won't be able to drill down on which map calls are actually slow things down. Just curious how does anyone tackle this. Currently I had to realize every map call to have a detailed view of the function calls - which I feel it's not using clojure to its full potential (and render reducers useless in my case)

hiredman08:04:22

if you don't realize it, it doesn't happen, so you cannot time it

hiredman08:04:48

how would you expect timing to work without realizing the seq?

hiredman08:04:33

reducers are just the same in this regard, if you don't actually do the work, you cannot time it

ronaldsuwandi08:04:41

@hiredman yeah, i’m just curious if there’s another way of doing this because if i realize at every step, it defeats the whole purpose of lazy-seq or reducers

ronaldsuwandi08:04:02

and also curious if anyone else is doing the same thing and i’m not the only one doing it this way 😄

hiredman08:04:13

I suspect you really want a profiler, which time is not

hiredman08:04:21

if you are just doing microbenchmarks, even then using time can be suspect (you should check out criterium)

mpenet08:04:29

time the operation you apply over every record, it makes no sense to time the iteration (or the creation of a LazySeq)

hiredman08:04:57

if you are trying to meaningful understand the performance of a large amount of code, consider something like visualvm

mpenet08:04:14

-> criterium also, time is not good

hiredman08:04:56

if you map a function f over a collection, a profile like visualvm, will show you the total runtime of f as your system runs, regardless of where you end up realizing the seq

ronaldsuwandi09:04:06

well my use case is that i have a webserver and some endpoints are more expensive than others. I used clojure-metrics which in turns uses codahale metrics in the backend

ronaldsuwandi09:04:28

and i created a graphite chart to show the response times for each endpoint, but some endpoints are slower so for those endpoints I needed a breakdown

ronaldsuwandi09:04:48

on which functions actually taking up time

ronaldsuwandi09:04:18

so what i did was exactly like the first expensive call, i call metrics/time on a realized collection all the time

ronaldsuwandi09:04:47

because if i use lazyseq/reducers and if at one point suddenly response time is very slow, there’s no way to find out at which function it’s actually slow right

dm309:04:59

in that case you need to instrument the functions individually

seanirby09:04:30

how can I get my leiningen project version number at runtime in my application?

ronaldsuwandi09:04:37

so in the end my approach is the correct way i guess simple_smile

timgilbert12:04:15

@seanirby: One note, I’ve found that versioneer will work for some things when you’re running through leiningen, but then return nil at runtime if you compile to an uberjar and then run that

timgilbert12:04:48

It winds up getting a system property for myproject.version which I assume lein sets at runtime

timgilbert12:04:49

I wound up writing a static file into my jar at build time and falling back to it if versioneer returned nil for me (there might be a better way to do it)

timgilbert12:04:07

I think there is also a library somewhere which parses project.clj as edn, too, or you could do that by hand of course, but again if you compile to an uberjar you won’t necessarily have it around at runtime

lwhorton13:04:14

can i not write a defmacro to override .?

turbopape13:04:05

technically you can

turbopape13:04:27

and the runtime will warn you that you shadowed something

lwhorton13:04:31

do I have to do any sort of :refer-clojure :exclude [.]?

lwhorton13:04:45

or does a maccro override something that’s exposed?

turbopape13:04:29

but you must call it fully qualified (ns/.)

bronsa13:04:47

@lwhorton: @turbopape: you can neither exclude . nor will the runtime warn you that you're overriding it. . is not a normal Var, it's a special form, you cannot override it.

turbopape13:04:18

ok, but you can define it and use its qualified form

bronsa13:04:27

but you shouldn't

bronsa13:04:33

things will not work as expected

turbopape13:04:37

yes, I assume...

borkdude14:04:11

(130k loc Java -> 4k loc Clojure :P)

reborg14:04:13

well, that’s actually more 20K locs. 4K loc was when only the homepage was rendered by clj

urbanslug14:04:47

@borkdude: That’s just a pic, where’s the talk?

roberto14:04:47

the talk is happening at this moment

roberto14:04:51

look at the date

nkraft14:04:50

Is it being cast from somewhere?

seanirby14:04:58

@timgilbert: appreciate the detailed reponse. thanks!

eraserhd15:04:44

I keep having this idea that I want to maintain a fork of clojure on which a Java indenter (among other things) is being run.

eraserhd15:04:30

Purely automated transformations which get re-applied when new commits appear in the official repo.

bronsa15:04:14

having a properly indented clojure would be valuable if contributors could write patch on top of it rather than on top of the mess that's currently clojure's indentation, I don't see much point in a properly indented fork that's read-only

eraserhd15:04:51

@bronsa Really? Isn’t it generally assumed that code is read at least 10x for every change made? I would suspect this would be much higher for Clojure.

dm315:04:28

I think it's safe to assume that every Clojure developer knows the Clojure source by heart, no? simple_smile

donaldball15:04:26

Parsing the indentation is not where I have trouble when reading the clojure compiler source simple_smile

eraserhd15:04:11

@donaldball: where do you have trouble?

eraserhd15:04:38

(mind you, I’m not likely to actually do this, but I spend an inordinate amount of time thinking about it)

bronsa15:04:32

@eraserhd: Compiler.java is not exactly a prime example of obvious and understandable code

bronsa15:04:58

@eraserhd: thing is, if you're reading code for a change, that'll be formatted for clojure/clojure and not the re-formatted clojure, and will likely not apply there

eraserhd15:04:31

I would hope that people who want to make a change, make that change in the original repo. Making a change like that to clojure presumes one already understands how it works, which presumes they’ve already read the code… and that’s what this would be for.

eraserhd15:04:38

For reference, I’ve probably spent a dozen hours in the clojure code, and basically understand nothing. I assume I’d have to spend a dozen more before making any kind of patch.

bronsa16:04:11

sure, but I doubt people work by reading code for hours and then producing a patch simple_smile I know I certainly do the reading and writing/testing at the same time when I'm working on a clojure patch, and would find having a read-only repo neat for maybe a few hours. But having to switch back & forth between an indented file and the same file where I'm writing a patch? meh simple_smile

numberq16:04:13

How does (file-seq) decide what order to put the files in the return collection? From my minimal experimenting, it seems like the directory itself is always first, and then the rest in reverse order of file creation (this was tested without any subdirectories). Is there a way to change that without calling a sort around (file-seq)?

conormcd17:04:28

It relies on java.io.File/listFiles which does not guarantee ordering.

numberq17:04:15

Ok, thanks!

fasiha17:04:30

A fair bit of googling and reading clojuredocs has led me to believe that there's no really straightforward way to search a seq or vector for a "sub-seq" or "sub-vector", i.e., (magic-search-function [1 2 3 4 5] [2 3]) ; => 1 (in contrast to regexps and indexOf for strings). Is this correct?

jr18:04:55

you can use indexOf if you partition the collection with a step of 1

jr18:04:02

user=> (.indexOf (partition 2 1 [1 2 3 4 5]) [2 3])
1
user=> (.indexOf (partition 2 1 [1 2 3 4 5]) [4 5])
3
user=> (.indexOf (partition 2 1 [1 2 3 4 5]) [5 6])
-1

jr18:04:51

where the first argument of partition is the size of the collection you are looking for

user=> (def x [2 3])
#'user/x
user=> (.indexOf (partition (count x) 1 [1 2 3 4 5]) x)
1

jr18:04:12

(defn magic-search-function [haystack needle]
  (.indexOf (partition (count needle) 1 haystack) needle))

fasiha19:04:45

@jr thanks, that's indeed what I was doing—I had been thinking that was terribly inefficient but as I read more about lazy seqs, maybe they're just fine simple_smile

lvh20:04:15

apparently I have also forgotten how to regex; (re-find #"(?!index)[.]html$" (.getName f)) doesn’t “get anything like html, but not index.html”; instead it gets everything ending in html but doesn’t throw away index.html, apparently

conormcd20:04:08

You probably want (re-find #"(?<!index)[.]html$" (.getName f)). You had a negative lookahead where you needed a negative lookbehind.

lvh20:04:14

conormcd: Oh! That makes sense. Thanks!

conormcd20:04:50

You're welcome.

lwhorton20:04:10

I have a stupid question relating to (possibly) cond but maybe also just invoking functions with vectors… this is not doing at all what I would expect:

(defn read-hiccup [hiccup]
  (cond
    (empty? (first hiccup)) []
    (keyword? (first hiccup)) (conj [:keywword] hiccup)))
It should be a simple function that takes [:html] hiccup style syntax and just spits it back to me.

lwhorton20:04:39

But I keep getting Don't know how to create ISeq from: clojure.lang.Keyword. Which makes me think this is a foundational-level issue in understanding and not function design.

hiredman20:04:01

empty? only works on seqs

lwhorton20:04:22

hah. so stupid, thanks @hiredman .

hiredman20:04:09

empty? only works on things that the 'seq' function works on, I should say

lvh22:04:40

Hm. So, at some point yesql started insisting that you specify the {:connection db-spec} map when you call defqueries. That’s a little annoying; because I don’t know which db I’m going to call it on beforehand. Current versions of yesql raise an exception when you call it with a connection map anyway:

ArityException Wrong number of args (1) passed to: generate/generate-query-fn/query-wrapper-fn--22770  clojure.lang.AFn.throwArity (AFn.java:429)
Even though the fn in question claims to have that arg:
(meta create-table!)
{:name "create-table!",
 :arglists ([{} {:keys [connection]}]),
 :yesql.generate/source "CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);”}

lvh22:04:10

There’s an existing issue for that exception, but apparently it just thinks that you should know connections at compile time: https://github.com/krisajenkins/yesql/issues/91 Apparently I am not the only person to reach the conclusion that you can’t reasonably manage a connection now: https://github.com/krisajenkins/yesql/issues/99

lvh22:04:07

require-sql appears to be the way you do this, but apparently it’s just broken https://github.com/krisajenkins/yesql/issues/118