Fork me on GitHub
#off-topic
<
2019-11-20
>
jaihindhreddy11:11:51

Can I print the bytecode of a compiled function at the REPL? Just curious.

jaihindhreddy11:11:22

I know I can touch the three parts, the name, the var, and the function itself, but can I print the function's code?

schmee11:11:53

no.disassemble is amazing ❤️

jaihindhreddy12:11:19

Thanks guys! 💯💯

sogaiu02:11:06

fwiw, there was this nice article that touches on this topic too with some practical advice: http://clojure-goes-fast.com/blog/introspection-tools-java-decompilers/

thanks2 4
Eric Ihli18:11:10

Anyone good with statistics? I'm trying to answer a question. If I scratch 100 lottery tickets, what can I expect my winnings/losses to be within 66% of the time, 95% of the time, etc...? I'm not sure what words to use to describe this. I think it's something like "I want to see the graph of the cumulative distribution function for 100 scratches of a particular scratch off lottery game"?

Alex Miller (Clojure team)18:11:07

I think that's more probability (specifically combinations) than statistics

Alex Miller (Clojure team)18:11:33

although maybe when you include the distribution you get there

sogaiu19:11:59

66% and 95% sound very standard deviation like numbers.

sogaiu19:11:39

phrases like "within 1 standard deviation" and "within 2 standard deviations" seem possibly relevant

Eric Ihli19:11:36

I think what I need are the formulas in this stackexchange post. But nothing is making sense. https://stats.stackexchange.com/questions/6534/how-do-i-calculate-a-weighted-standard-deviation-in-excel

Eric Ihli19:11:01

# (prize_value, num_prizes_in_game)
# In statistics terms, I think this is: (observation, weight*)
# *Once we convert the scalar number of tickets to percentages
# by dividing the number of tickets at each prize level by the total
# number of tickets in the game.
tickets = [
    (15e6, 4),
    (1e6, 13),
    (1e5, 4),
    (2e4, 351),
    (1e4, 358),
    (5e3, 1066),
    (1e3, 24488),
    (500, 52608),
    (200, 175536),
    (100, 825885),
    (50, 1409291),
    (40, 2116878),
    (30, 3534425),
    (0, 13051157),
]

total_num_tickets = sum(t[1] for t in tickets)
scratch_tickets_percentages = [(t[0], t[1] / total_num_tickets) for t in tickets]

# Since we converted the weights to percentages, this is simply 1.0
# And since the sum of the weights is 1.0, we don't really need
# to divide by it in the following formula. But I'm leaving it there
# for reference because I'm not sure if I should have converted the number
# of tickets into percentages. Will that affect anything? Is it
# effectively the same going forward?
sum_weights = sum(t[1] for t in scratch_tickets_percentages)
weighted_mean = sum(
    weight * val
    for val, weight in scratch_tickets_percentages
) / sum_weights

sum_of_squares_of_weighted_means = sum(
    weight * (val - weighted_mean) ** 2
    for val, weight in scratch_tickets_percentages
)  # AKA variance

Eric Ihli19:11:13

Sorry for the Python, but off-topic eh? That gives me a variance of 43095998 (standard deviation of 6564), but what is that the answer to? $6,564 is obviously not the standard deviation of buying a single $30 lottery ticket. It's also obviously not the standard deviation of buying every ticket in the game. So while I think I followed the formula correctly, I'm not sure what question that formula is answering.

Eric Ihli19:11:29

End goal of this is I want to plug numbers into a formula, like https://stackoverflow.com/questions/10138085/python-pylab-plot-normal-distribution, and get a visualization of where I can expect to be after 10 tickets, 100 tickets, etc...

Alex Miller (Clojure team)19:11:15

I'm going to save you the trouble and say you will be down :)

😆 17
Drew Verlee22:11:23

What's a good way to keep up with version changes on a project? (Clojure, JavaScript, java etc...) To know what new features are in a version. For instance, if I have a clojure project It would be nifty if you could subscribe to get notified if any deps had new versions and see those changes in a uniform way. Or as a point on time manual tool. Such a view would depend on people writing a changelog in the same way. Tag on question, do changelogs have a specification?

plexus12:11:03

This is as close to a spec for changelogs as you'll find I think https://keepachangelog.com/en/1.0.0/

jjttjj22:11:14

This might be hard to give general advice on, and it also might be fairly arbitrary, but when it comes to the data structure of an event type that components of a system communicate, do people prefer vectors ie [:new-message/dogs {:payload 123 :timestamp 12345 :id 11} or maps like {:event/topic :new-message/dogs :event/data {:payload 123 :timestamp 12345 :id 11} :event/timestamp 12344} ? The vector style feels a bit nicer to type out when dispatch is usually based on topic, or when events are nested. however the map is easier to extend over time and more flexible, and I've found that it's pretty common in my usage to dispatch on something other than topic anyway. Anyone have any thoughts on this?

Drew Verlee22:11:40

i perfer the hashmap, vectors are best for items where the order implies something. Here the order implies what the values are, which is better reflected by keys in a map.

Drew Verlee22:11:23

I think the exception to this is if your very sure your api will be stable forever, then using values in a list might be ok bc it reduces the overhead. e.g anything in core, etc..

jjttjj22:11:19

Yeah that's an interesting point too about the ordering. back to the nested/wrapped events, the ideal case for the vector events seems to be when dispatch is solely based on topic aka event-type aka first vector item. In that case it's a case of "first, what is the type of this thing, then based on that type hand the thing itself somewhere"

Drew Verlee22:11:16

i'm not sure what context the question is asked in. But i would like to see more event dispatch systems do dispatch like clojure does multimethods where it can be done off arbitrary code. For one, i quickly found that event names overlaped :logout-x :logout-y , etc.. As opposed to at least having it be tagged based [logout][x] [logout][y]

Drew Verlee22:11:00

there was a post on clojurverse that also talked about the pros and cons of using data for code in that context.

Drew Verlee22:11:35

it was a heavy topic, so i can't really summarize it, but it was from a week or so back, might be worth digging up if your building such a system.

jjttjj22:11:08

Cool I'll try to find it

sogaiu22:11:35

have been curious why vectors are used sometimes -- would like to hear why 🙂

Cameron22:11:45

The way I often like to think of it in general is that data is the raw representation of an idea, the language for the idea, and is a mapping of keys to values. The vector is a shorthand, an implicit mapping of integers to values (by position) that themselves often are implicitly supposed to represent some other key. So the map is the explicit data, the vector is implicit shorthand

👍 4
Andy Wootton09:11:25

I'm a Clojure learner, coming from a distant procedural language history but I've been thinking about this a lot. A vector is values/facts, onto which our mind projects an idea. A mapping of keys with meaningful names makes the idea more explicit. It is human-readable meta-data about declared knowledge. The data that is code is how-to knowledge. Data, facts and knowledge may all be wrong and need to be corrected later. Immutability allows the changes to be audited.

Cameron22:11:00

(I'm speaking highly in the general -- not necessarily specific to this case)

jjttjj22:11:35

@sogaiu I've been using the vector style for awhile and it does feel nicer to me to type out and destructive. [:component/foo [:component.foo/bar {:args-for :bar}]] can be nice when you multiple levels of routing, one to pass the message to the :component/foo handler and then that handler knows how to deal with the :component.foo/bar message. This is nicer to type and destrucure than the nested map alternative.

sogaiu22:11:27

the places i've seen vectors that come to mind immediately are: unrepl, re-frame, and punk

jjttjj22:11:33

(all that said I'm leaning towards switching to maps)

jjttjj22:11:46

sente is where I was originally introduced to it

jjttjj22:11:34

@zdot101 that's a good point too that a vector is basically just a map anyway

sogaiu22:11:42

@jjttjj hadn't thought about the multiple levels -- thanks for mentioning that

Cameron22:11:47

aha well I'm carefully trying to call it a mapping in place of a map -- I feel like the words map and vector are themselves the perfect words to use when differentiating between these kinds of mappings

Cameron22:11:54

its so hard to find language sometimes for this sort

Cameron22:11:56

because its so precise

Cameron22:11:13

Examples btw where we use a similar sort of mapping with implicit meaning is lisp lists / function calls themselves! You could have written things like {:fn add :args [1 2 3]} and called the language MAPP but we stuck with the shorthand of (fn arg1 arg2 arg3) ahaha

jjttjj22:11:56

also hiccup vs clojure.data.xml

Alex Miller (Clojure team)23:11:03

vectors are inherently positional, and thus have implicit attributes

Alex Miller (Clojure team)23:11:58

implicit usually means something is hidden/assumed - the tradeoff is typically that it's easier to type, more concise, but also less explicit about meaning

Alex Miller (Clojure team)23:11:35

implicit also typically means it's more fragile (harder to extend without violating assumptions)

Alex Miller (Clojure team)23:11:33

one common dodge here is to base your api on the explicit form, but support an implicit form for ease of use and a means of transforming from implicit to explicit

Alex Miller (Clojure team)23:11:36

often the explicit form is more amenable to programmatic transformation and manipulation too

Cameron23:11:43

ah and here I almost wrote something like that; what I was going to say is 'if I was going to use a short form, I'd often still want an explicit form underneath it as the base'

Alex Miller (Clojure team)23:11:54

the tradeoff for doing both is of course - more code, bigger api

Cameron23:11:19

but then I started getting into a conversation with myself over the trade offs and left it

jjttjj23:11:20

cool, I hadn't considered doing both

Alex Miller (Clojure team)23:11:45

you can look around and find lots of examples all across this set of dimensions

Alex Miller (Clojure team)23:11:22

full let bindings = explicit, destructuring = implicit (there is an undocumented function destructure that converts from destructuring forms into let bindings)