#clojure logs

2011-04-23

00:16joshua__So I wrote a function I found cool because I heard about it being used in a different language. After writing it I realized that the Haskell implementation of the function was a thousand times shorter and I'm starting to feel a little bit ashamed. How can I shorten this up? Or just make it better? https://gist.github.com/938272
00:17joshua__*was a thousand times shorter is an exaggeration.
00:17amalloyjoshua__: don't unroll the variadics. that's a grossness in clojure.core for speed
00:17clojurebotclojure is not scheme
00:18joshua__amalloy, oh. I guess I won't use Alt-. for Clojure advice in the future o.0
00:18amalloyjoshua__: take advice from any of the namespaces except clojure.core
00:22joshua__amalloy, can you do something like (apply f more) when more is what was in [& more] when more is empty?
00:22amalloyjoshua__: if f is willing to accept 0 arguments
00:23amalloy&(apply + [])
00:23sexpbot⟹ 0
00:23joshua__(+)
00:23joshua__&(+)
00:23sexpbot⟹ 0
00:23joshua__Alright. Sweet.
00:33joshua__Alright. So I think this is better. What do you guys think? https://gist.github.com/938272
00:34joshua__Actually hold on I just had a better idea.
00:34amalloyjoshua__: you're aware that this has been written a few times already, right? this is just an intellectual exercise?
00:35joshua__amalloy, This is just an exercise yes.
00:35joshua__amalloy, although I wasn't aware it had already been written.
00:35amalloyjoshua__: there are plans to include it in clojure 1.3 as
00:35amalloywell
00:36joshua__amalloy, Ah! So I was onto something cool after all!
00:36amalloyyes. a lot of people want this
00:38carllercheSo, a slightly silly question... what's a good way to indent letfn? No matter how i try, it feels weird to me :P
00:40dnolencarllerche: gist of how you're indenting now?
00:41joshua__Alright. So I think this is the readable version I like: https://gist.github.com/938272
00:41joshua__Sorta fun. I got to write the performant unrolled variadic version and the concise version of the same function. First time I've done that in clj.
00:42carllerchednolen: https://gist.github.com/4164c496b1efad098fe9
00:43amalloycarllerche: that's about the only way you can do it
00:43amalloyyou could move [x] and [y] to the same line as first-fn if you want
00:44dnolencarllerche: I'd do it like this, https://gist.github.com/1d7c2f86b42a6b13aef0
00:44dnolenScheme letrec style is reference here.
00:45dnolenas well as the style you'll find in Clojure source itself.
00:46carllerchehmm, ok
00:48dnolenthis typestate thing in Rust is kinda interesting ...
00:51joshua__Alright. So am I misunderstanding something or is currying a special case of partial application?
00:53joshua__Nevermind. I was misunderstanding.
00:57joshua__So currying is when you have to use say.. ((((foo a) b) c) d) but partial application could be ((foo a) b c d). So currying wouldn't be a special case, because it doesn't have the consume one arg until all are consumed requirement.
01:52amalloyanyone happen to know what css to apply, to make a link never show as visited?
01:52amalloyhaving a terrible time searching for it
02:41midsamalloy: would applying the same style of a:link to a:visited work for you?
02:42amalloymids: yeah, i figured it out. i just thought there was a builtin class for it so i didn't want to build it myself
02:46peteriserinsare there clojure naming conventions like the ones for CL at http://www.cliki.net/naming%20conventions?
03:17amalloypeteriserins: we mostly borrow from scheme
03:17amalloyfoo!, foo?, names-with-hyphens
03:17amalloyfoo*
03:52thorwilhmm, how do i regex match a linebreak, except if it sits between </p> and <p>?
03:57midsthorwil: look into negative look-ahead (?!regex)
03:57thorwil#"[^(</p>)]\r\n[^(<p>)]" works almost, except that it eats one chaaracter before and after replacement
03:59thorwilah, #"(?!</p>)\r\n(?!<p>)"
03:59thorwilthanks, mids
03:59midsmight also want to inject a \s* or two
04:02thorwilnormally yes, but these sequences are generated by my code, so no extraneous whitespace
06:24matthias__ugh, how do i access a member variable of a class in clojure? :|
06:27thorwilmatthias__: look if the class has something like .getValue?
06:29matthias__what i'm trying to access is not a method
06:30matthias__hmm, it does have a getter for it
10:41matthias__i want to add a reference to a java class to the state of a class that im deriving from another javaclass. havint trouble finding out how to do that :|
10:42matthias__acutally im translating a java tutorial for the jmonkeyengine into clojure and they use a protected field which is declared and then initialized in some method and updated in an update method
10:42matthias__dont know how to do it in clojure
10:42matthias__http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_main_event_loop there's the code
10:57kzarI'm setting up a project using appengine-magic and moustache, does anyone know how to serve static files and where to put them? Looking at tryclojure's source you can make a resources/public directory and put everything in there, but I'm missing a special route or something because the files aren't served. (Also ideally I would want "/css/example.css" instead of "/resources/public/example.css".)
10:59midskzar: which version of appengine-magic?
10:59kzarmids: I'm using the latest one I think, 0.4.1
11:00midsiirc 0.3 was resources/, 0.4 is war/
11:01kzarmids: To be fair I've tried both, I originally had a problem loading templates with enlive until I put them in resources, (war didn't work).
11:01kzarmids: Do you need to add a route or should it work automatically?
11:01midswell, templates isnt static stuff
11:02kzarmids: Yea that's true
11:02midsfor example I have my css under war/css/mysite.css
11:02thorwilkzar: templates under resources, static files under war
11:03thorwilkzar: routing is explicit
11:03kzarAh it's working
11:03thorwilthough it might be easy enough to construct your own filename/path based routing
11:03kzarSorry I don't know what I messed up first time when I tried putting them in the war directory
11:06thorwilthe list of things that didn't work the first time i tried them, only to just work later after unknowingly removing some issue, is long :)
11:08thorwili wonder what would it take to build an interface allowing the javascript that i serve to call clojure functions on the server, without opening an attack vector
11:09kzarthorwil: Doesn't tryclojure do that?
11:09midsdirectly? or through some json / rest interface
11:11thorwilmids: the idea would be to minimize the amount of code on both sides, so whatever works in that light
11:13thorwilkzar: hmm, security shouldn't come from limiting what can be called, but rather from differentiating between JS that was served, ws JS that has been shoved in by an attacker
11:38pdkis anyone here familiar with writing bots that take an event for when an email inbox receives a message then doing something with the message
11:39pdkbasically i'm trying to jury rig something like hootsuite since hootsuite doesn't work for wp sites that are self hosted
11:39pdkrather between wp and constant contact for someone i'm helping to make a site for
11:40matthias__so, there's a bunch of ways to keep a reference to a mutable object. i dont know what to use. i need an instance of a java class that i can change and have it sotred inside another java class which is define with gen-class. it derives from a another java class. how do i do that?
11:50markomanis there a way to make keyword :author to function call without if else, switch case or condp structures? call would be similar from: (:author "Shakespeare, William") to: (Author. "Shakespeare, William")
11:52hyperboreeanhow can I expand in clojure ~/myfolder to /home/myuser/myfolder?
11:52markomanit could as well be a string transformed to function call (#"Author." "Shakes...") or something like that
11:59markomanhyperboreean: have you looked at "file system utilities for Clojure" ?
12:00hyperboreeanmarkoman: googling for clojure (file|paths) gives me only links to people showing how to install clojure and nothing related to clojure libs
12:01hyperboreeanI'll try your suggestion, thanks
12:01tufflaxmatthias__: I don't know if this is what you meant but: atoms, refs and agents should *not* refer to mutable things. The only things that is mutablu is the references themselves. If you want mutable in the java sense then maybe you can do it with gen-class but i don't know... was that what you were asking? :p
12:02matthias__yes
12:02matthias__i need a mutable object in my class
12:04tufflaxis the object something that could be implemented as a clojure data structure?
12:06matthias__its already implemented as a java class in jmonkeyengine
12:06matthias__trying to work with it using clojure
12:08hyperboreeanmarkoman: ok, I found exactly what I needed: fs; sorry to bug you, but is there any way I can specify to lein from where it can get the dependencies? as far as I can see from the docs, that's not possible
12:09matthias__:repositories?
12:09tufflaxwell you don't need anything special to refer to mutable objects, just refer to them! the ref types in clojure is just a way to achieve mutability when the "things" themselves are not
12:10matthias__well, im trying to add it to the class as a member
12:10matthias__hmm, or maybe i can just make it global
12:11tufflaxi havent used gen-class much, so i don't see your problem, sorry
12:11markomanhyperboreaan: yes, fs seems to provide basic file system functionality. lein: so far i have just used inc and require within project src and jars. try what matthias told
12:12hyperboreeanwill do, thanks guys!
12:12markomannp :)
12:14Chousukedeftype supports mutability
12:15markomanto my own question. i found this ##(#=(symbol "println") "hello") is it going to give problems? I mean my functions are derived from java classes Author.
12:21markomanwell it gave problems already. my initial was to use keywords for function names so assumed this would work:
12:21markoman.(#=(symbol (name :println)) "hello")
12:21markoman,(#=(symbol (name :println)) "hello")
12:21clojurebotEvalReader not allowed when *read-eval* is false.
12:23hyperboreeandoh, fs is in clojars, no need to get it from bitbucket ... noob!
12:27matthias__so if i want to declare a reference (the java kind of reference) and then later assign it so some object, how do i do that? i mean wahts the clojure equivalent of = ?
12:27TimMcmarkoman: ##((resolve 'println) "hello")
12:27sexpbotjava.lang.SecurityException: You tripped the alarm! resolve is bad!
12:28TimMcmatthias__: What do you mean "the java kind of reference"?
12:29matthias__well if i say Integer bla = null; in java, then bla is a "reference"
12:30TimMcYou don't get those in Clojure.
12:30TimMcClojure has reference types, though.
12:31matthias__if i say (let [bla (new Integer 320409)]), what's bla?
12:31TimMcbla is the name that binds an instance of Integer
12:31TimMcThat instance is a *value*, not a reference.
12:32matthias__well, what i really want is to have a way to make some kinda reference to an object, but i want to actually make the object later
12:33TimMcmatthias__: There are refs, vars, agents, atoms...
12:33TimMcI would bet however that you don't even need one of those.
12:34TimMc(I don't know what you are trying to accomplish in general, though.)
12:34TimMchttp://www.clojure.org/refs
12:35matthias__trying to translate this http://jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_main_event_loop to clojure
12:35matthias__the player is what i dont know how to do
12:36matthias__(it doesnt matter if it's actually a member of the class or not, since the class is only instantiated once)
12:39TimMcmatthias__: For something like that, I would tend to have a ref holding the game state (which would be a map or record or other associative type), and have an updater function that takes old state -> new state.
12:41matthias__hmm, but then i'd have to remove the player every frame and make a new one. afaik, clojure does some things to make that functional style more efficient, but what if its just a java object? i'd have to do the same with everything in my game. i wanna kind of decouple all that functional stuff and only pass the values into jmonkeyengine at the end of every frame
14:02matthias__im trying to use (declare player) and then later bind an object to it with (binding [player (new Geometry "blue cube", b)]). but it doesnt seem to work
14:04pdk(doc binding)
14:04clojurebot"([bindings & body]); binding => var-symbol init-expr Creates new bindings for the (already-existing) vars, with the supplied initial values, executes the exprs in an implicit do, then re-establishes the bindings that existed before. The new bindings are made in parallel (unlike let); all init-exprs are evaluated before the vars are bound to their new values."
14:06matthias__yes i read that
14:07matthias__is it supposed to make it obvious why what im tryign doesnt work? :p
14:07TimMcmatthias__: I think you want def, not declare, if you're going to use binding.
14:10matthias__oh, binding only changes the vars for its own body
14:11matthias__i dont understand the difference between (def x) and (declare x)
14:11matthias__(doc def)
14:11clojurebotDENIED
14:11matthias__awww
14:11matthias__(doc declare)
14:11clojurebot"([& names]); defs the supplied var names with no bindings, useful for making forward declarations."
14:13matthias__trying set! instead of binding now, but it doesnt work. says cant change root binding
14:15codsHi. I can't find how to access an enum value declared within a class. I want to get "launchPermission" from this class: http://code.google.com/p/typica/source/browse/trunk/java/com/xerox/amazonws/ec2/ImageAttribute.java
14:15codsonce I import ImageAttribute, what is the syntax to get the enum value?
14:16codsI tried various thing like ImageAttribute/ImageAttributeType/launchPermission, but it's wrong.
14:21codsAny idea? I'm sure it's an obvious mistake, but even reading http://clojure.org/java_interop is not enough to figure what is wrong. (I know Java only a bit)
14:21matthias__(doc atom)
14:21clojurebot"([x] [x & options]); Creates and returns an Atom with an initial value of x and zero or more options (in any order): :meta metadata-map :validator validate-fn If metadata-map is supplied, it will be come the metadata on the atom. validate-fn must be nil or a side-effect-free fn of one argument, which will be passed the intended new state on any state change. If the new state is unacceptable, the validate-fn should return
14:25matthias__can i declare an "empty" atom and then put in a java object later with swap!?
14:26TimMccods: The enum is an inner type.
14:26TimMccods: Import ImageAttribute$ImageAttributeType, then use ImageAttribute$ImageAttributeType/launchPermission
14:27TimMcmatthias__: You can make an atom containing nil.
14:28codsTimMc: ah ok. Thanks a lot!
14:28TimMcTricky little bastard, innit?
14:28TimMcAlso, horribly verbose.
14:28matthias__"java.lang.ClassCastException: com.jme3.scene.Geometry cannot be cast to clojure.lang.IFn
14:28matthias__"
14:29matthias__(def player (atom nil)) ... later: (swap! player (new Geometry "blue cube", b))
14:29TimMccods: On my personal wishlist is a renaming clause for import.
14:29matthias__that's what i tried
14:29TimMcmatthias__: swap! takes a function from old state -> new state
14:29matthias__(doc swap!)
14:29clojurebot"([atom f] [atom f x] [atom f x y] [atom f x y & args]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."
14:30TimMcmatthias__: (constantly foo)
14:30matthias__(doc constantly)
14:30clojurebot"([x]); Returns a function that takes any number of arguments and returns x."
14:32matthias__ookay... now it seems to work, thanks. i'm more like "oO" than "aha" though ;)
14:34devnname that tune: the song that plays at the beginning and end of the sicp lectures
15:08arohnerI have a vector, and I'd like to stick an element in it conditionally. I remember there's a trick using splicing, but I can't remember it
15:08arohneri.e. [1 2 (if (foo? x) x)]
15:08arohnerbut there was a way to use ~@ to make the list have two elements rather than 3 when the if is false
15:08arohneranyone know what I'm talking about?
15:09arohneroh
15:09arohner&&`[1 2 ~@(when true 3)]
15:09sexpbotjava.lang.Exception: Unable to resolve symbol: & in this context
15:09arohner&`[1 2 ~@(when true 3)]
15:09sexpbotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
15:10danlarkinthat's probably the wrong path to take
15:11danlarkinare you working with a literal vector like that? or conjing up stuff
15:14arohnerdanlarkin: I'm working with a literal vector of hiccup html
15:15danlarkinok, so depending on (foo? x) you want a literal vector of 1 & 2 and maybe x
15:15arohnerright
15:16danlarkinso of course there's (if (foo? x) [1 2 x] [1 2])
15:16danlarkinis the vector so monstrous that that's ugly?
15:16arohnerdanlarkin: yeah
15:16arohnerI want to do this with multiple values in the vector
15:17arohnerthere's always (filter identity [ 1 2 (when (foo? x) x)]), but I'm curious if there's anything better
15:17danlarkinperhaps this then: (let [v [1 2]] (if (foo? x) (conj v x) x))
15:18danlarkinI always prefer (remove nil? ..) to (filter identity ..)
15:18danlarkinbut that's just preference
15:53tufflax#jasmin
15:54tufflaxsorry
16:00amalloy&`[1 2 ~@(when true [3])]?
16:00sexpbot⟹ [1 2 3]
16:00amalloyarohner: ^
16:00danlarkingross
16:01amalloydanlarkin: i don't think so
16:01kzarProbably a dumb question but where am I going wrong here? ,(sun.misc.BASE64Decoder. "ZXhhbXBsZQ==")
16:01kzar(balls I thought , would get the bot to eval it.)
16:01amalloykzar: , and & only work at the start of a message
16:01amalloyyou can use ## mid-message
16:02amalloyeg to see what sexpbot thinks of ##(sun.misc.BASE64Decoder. "ZXhhbXBsZQ==")
16:02sexpbotjava.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.misc)
16:02kzaramalloy: ah gotya, I'm sure you've told me that before I just got deja vu.. either that or there's a glitch in the matrix
16:02amalloygood. i was going to say, what you're doing wrong is using sun.misc :P
16:02amalloy$google apache commons binary encoder decoder
16:02sexpbotFirst out of 8360 results is: Base64 (Commons Codec 1.5 API) - Apache Commons - Apache Commons
16:02sexpbothttp://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64.html
16:03danlarkinsyntax-quoting there is all well and good when you're using numbers
16:03danlarkinbut when you want to evaluate other things in the vector then you have to balance the unquotes and blah
16:03danlarkinugly town
16:04amalloydanlarkin: yes. if arohner wants to refer to the same gensym in the normal part of the vector and the "maybe" part, he'll be sad
16:05danlarkinnot quoting it seems cleaner to me
16:06amalloydanlarkin: ##(into `[1 2] (when true `[4]))?
16:06sexpbot⟹ [1 2 4]
16:06kzar,(apply str (map char (seq (org.apache.commons.codec.binary.Base64/decodeBase64 "ZXhhbXBsZQ=="))))
16:06clojurebot"example"
16:07kzar:) thanks guys
16:07amalloywhoa
16:07amalloyi'm surprised clojurebot has apache commons on his classpath
16:08danlarkinamalloy: that's nice
16:08danlarkinbut you don't need all that quoting
16:08amalloydanlarkin: not for numbers, obviously
16:08amalloybut i get the impression that arohner will :P
16:08danlarkinoh, yeah, I don't know what hiccup html means
16:08danlarkinif it has to be quoted I guess yeah
16:09arohnerdanlarkin: http://github.com/weavejester/hiccup
16:10amalloyi haven't needed to quote any hiccup yet, but we'll see
16:10kzarWhat's wrong with having this in my namespace? (:use [org.apache.commons.codec.binary.Base64 :only [decodeBase64]])
16:10amalloyat least two things are wrong there
16:10amalloy(1) apache stuff is java classes, not clojure namespaces. it wants an import
16:10amalloy(2) you can't import just a method - you need to import a whole class
16:11amalloy(3) you need to add a dependency on commons-codec in your project.clj to actually get that library from the net
16:13Bronsawhy in clojure-1.3-alpha6 1 is a java.lang.Long and not a java.lang.Integer?
16:16arohnerBronsa: it has to do with primitive support in clojure fns
16:16arohnerBronsa: i.e. unboxed math. 1.3 can create fns that take unboxed Longs and Doubles
16:17kzaramalloy: whoop, got it working tah
16:18arohnerthe clojure fns have to implement an interface, clojure.lang.IFn, and rhickey didn't want the interface definition to explode with every permutation of taking a short, an int, a long, a float, etc
16:18arohnerso if you want primitive fns, the fn can take longs or doubles, and all literal numbers are one of those two
16:18Bronsaok
16:18Bronsathanks
16:18arohnerif you really need an int, you can still do (Integer. 5)
16:19amalloyarohner: ##(class (int 5))
16:19sexpbot⟹ java.lang.Integer
16:19arohneroh, cool. That didn't work in an earlier alpha, so I got out of the habit
16:19arohner##(class 5)
16:19sexpbot⟹ java.lang.Integer
16:20arohneramalloy: sexbot doesn't appear to be running 1.3
16:20amalloyarohner: no
16:20amalloybut i thought that (int foo) would cast fine?
16:20Bronsawell
16:20amalloy&(int (long 5))
16:20sexpbot⟹ 5
16:20Bronsauser=> (class (int 4))
16:20Bronsajava.lang.Long
16:20Bronsain clojure 1.3.0-alpha6
16:21amalloyhah, okay. well, silly me
16:24kzar$google apache commons hmac
16:24sexpbotFirst out of 872 results is: webhooks - javax.crypto.SecretKey implementation for encoding ...
16:24sexpbothttp://code.google.com/p/webhooks/
18:27kzarIf I've done [clojure.string :as str] how come I still see warnngs about replace and reverse already existing in the namespace? (I thought the ":as str" bit would fix that.)
18:28kzarSorry I meant to type (:use [clojure.string :as str]) there
18:28amalloy_kzar: you want require, not use
18:30kzaramalloy: Ah right, that fixed it. How come?
18:30amalloyuse imports the unqualified symbol into your namespace, period. it doesn't pay attention to an :as clause
18:31kzarah gotya thanks
18:55TimMcamalloy: The silent failure on :as has caused me much consternation in the past.
19:25devndamnit kzar, come back! i have a link for you!
19:25devnhttp://blog.8thlight.com/articles/2010/12/6/clojure-libs-and-namespaces-require-use-import-and-ns
20:49chrissbxIs there some overview over the clojure language? I'm repeatedly finding myself not finding what I need in the reference.
20:49chrissbxLike, how are exceptions to be raised?
20:49Rayneschrissbx: http://java.ociweb.com/mark/clojure/article.html Is precisely what you describe, methinks. It's good, if a little outdated.
20:50dnolenchrissbx: like how to throw one?
20:53chrissbxyes; I'm going to read that article
20:55dnolenchrissbx: http://clojuredocs.org/clojure_core/clojure.core/throw
20:57riendoes closure have a hands-free .dmg install file for the mac?
20:57rienI'm following the step by steps, setting up classpath variables, and nothing works
20:58amalloy$google leiningen clojure
20:58sexpbotFirst out of 2290 results is: Building Clojure Projects with Leiningen « I am Zef
20:58sexpbothttp://zef.me/2470/building-clojure-projects-with-leiningen
20:59znutar_is load-string equivalent to (conj eval read-string) ?
20:59amalloyrien: get the lein script, run it, and it installs everything
20:59znutar_er, (comp eval read-string)
20:59rienamalloy: trying it right now, thanks
21:00rienlol it's made by technomancy!
21:00rienthat's good, I trust his stuff
21:02chrissbxThanks dnolen & Raynes
21:49seancorfieldrien: if you get stuck with lein, just holler... i use it all the time for my projects on a mac!
22:59technomancyrien: heh; thanks. have I run into you before somewhere else on this wide inter net?
23:11technomancythere's got to be a better way to say this: (into {} (for [[clause-type & parts] clauses] [clause-type parts]))
23:11technomancybut it eludes me
23:12amalloy(into {} (map (juxt first rest) clauses))?
23:12technomancyamalloy: but of course!
23:12technomancythanks =)
23:12amalloywelcome
23:13technomancyhah; I had (merge {:a foo :b bar} (into {} [...]))
23:13technomancyI don't know why I keep forgetting into can have a non-empty first arg.
23:25seancorfield__amalloy: you sure like juxt :)
23:26amalloyseancorfield__: you saw how well it solved that problem. it's the best for everything!
23:30seancorfield__it is a pretty slick solution in that case
23:36seancorfield__i probably need to review my code and see if could help simplify anything.:)
23:36amalloyseancorfield__: i overused juxt recently
23:37seancorfield__did you hurt yourself? :D
23:37amalloyhttp://twitter.com/#!/alanmalloy/status/61897979136708608 (spoiler for 4clojure #53, so don't look if that bothers you)
23:38amalloyi needed to turn [[0 1] [1 2] [2 3]] into [0 1 2 3], so i used (juxt ffirst (partial map second))
23:57technomancythere's no pprint-for-code, is there?
23:58seancorfield,(distinct (apply concat [[0 1] [1 2] [2 3]]))
23:58clojurebot(0 1 2 3)
23:58KirinDavetechnomancy: Got a sec?
23:58seancorfieldah, not a vector :)
23:58seancorfieldi have not actually looked at 4clojure yet so i don't even know what you're trying to solve
23:58amalloyseancorfield__: i actually was thinking i needed to account for non-distinct elements of the list, but i don't
23:59technomancyKirinDave: sure
23:59KirinDavetechnomancy: I'm writing a bunch of assignments for a jc programming class.
23:59KirinDavetechnomancy: I just finished the first assignment, was wondering if someone could check it out and tell me if it's a turrible plan
23:59KirinDavetechnomancy: https://gist.github.com/raw/ac64ad91fb52e0964a1b/954aa172f8ee08cb56e29816ee14508c89699b5f/project0.txt