|
Gloss is pretty nice
|
# ? May 30, 2015 01:23 |
|
|
# ? May 2, 2024 23:44 |
Testiclops posted:Gloss is pretty nice I'm looking over it now and it seems pretty promising. Thanks!
|
|
# ? May 30, 2015 01:54 |
|
Yeah, gloss for sure. It's so handy when doing exactly this kind of simple interactive 2D display that you want. I'm working in F# and I can't find anything like it, I really don't want to have to go all the way to UE4
|
# ? May 30, 2015 10:08 |
|
gonadic io posted:Yeah, gloss for sure. It's so handy when doing exactly this kind of simple interactive 2D display that you want. I'm working in F# and I can't find anything like it, I really don't want to have to go all the way to UE4 Something like OpenTK? I haven't used it, but it looks like a good library for doing graphics. Linky: http://www.opentk.com
|
# ? May 30, 2015 10:37 |
|
Hi, Haskell newbie here. I was wondering why main doesn't have a [String] -> IO () type signature like other programming languages, like C/C++ or Java. It would be pretty cool, thanks to pattern matching, to be able to do things like this:code:
Smoke_Max fucked around with this message at 15:42 on Jun 3, 2015 |
# ? Jun 3, 2015 15:38 |
|
I know it doesn't directly answer your question, but System.Environment.getArgs will give you that list of strings. As for why it's not there by default. No idea, historical reasons probably, and it'd be nontrivial to overload to change it now. edit: I'd probably do it like one of these two examples, depending on how fancy I was feeling at the time: code:
gonadic io fucked around with this message at 17:21 on Jun 3, 2015 |
# ? Jun 3, 2015 16:27 |
|
You could do something likecode:
|
# ? Jun 3, 2015 17:27 |
|
Smoke_Max posted:Hi, Haskell newbie here. I was wondering why main doesn't have a [String] -> IO () type signature like other programming languages, like C/C++ or Java. It would be pretty cool, thanks to pattern matching, to be able to do things like this: That's a relatively arbitrary standardization of C -- main can actually take three arguments on some platforms: code:
It's a trendy way to make platform-specific stuff be in a platform-specific library, instead of having it be something that's in the "language". Other languages do it this way too. In Windows the command line is actually a single string, which you'll see if you use WinMain as the entry point, and you have to call GetCommandLineW to get the Unicode version. sarehu fucked around with this message at 00:49 on Jun 4, 2015 |
# ? Jun 4, 2015 00:43 |
|
Smoke_Max posted:Hi, Haskell newbie here. I was wondering why main doesn't have a [String] -> IO () type signature like other programming languages, like C/C++ or Java. It would be pretty cool, thanks to pattern matching, to be able to do things like this: This idea is pretty close to what main's signature actually is, if you imagine "IO a" to mean "World -> (a, World)", where World is the type of the rest of the universe. The main function takes a World, emits a value, and also yields a new World, just like other IO actions. Composing IO actions together amounts to threading successive World states through the calls. Unspecified system magic takes care of providing the initial World to the main function at startup. Part of the World is the arguments provided to the program. These are accessible not just in main, but anywhere that we have access to a World. Alternatively, it could make sense to split them off, so main had effective type [String] -> World -> ((), World); and then the arguments could be passed around explicitly wherever they were needed. Or the arguments could be provided as some global constant "args :: [String]", without even an IO type. (For example, this happens with System.Info.os :: String, since we expect the operating system name to be constant over the running life of the program). It so happens that Haskell decided to treat program arguments as part of the World. Now, we don't actually have access to World values for a few related reasons. One is that the design of IO as an opaque type allows implementers to not have to provide Worlds as a collection of state - IO can be implemented in other ways, much more conveniently. Also, if we could inspect World values, then we could do things which IO is designed to forbid, like saving World copies for later. So all the "get state from the system" style of actions ultimately need to make use of some builtin special functions to do the work, and have an IO type in order to achieve the proper sequencing of actions. The getArgs function is like this; with type "IO [String]" it is as if there is a World coming in (to pull some Strings from), which is provided by some call chain, within the IO monad, up to the initial state of the World provided to main. Another trick, by the way, is: code:
|
# ? Jun 4, 2015 01:43 |
|
While your analogy is nice, and the types are more or less on point, this explanation evades the real reason why main doesn't have any arguments: the STG machine needs a starting configuration, and doing so while abstracting over input makes a worse abstract machine. Setting up an STG machine with a main with no arguments makes a lot of sense, because you just build everything into the heap and then you can formally define "invoke main with no arguments" as the start configuration for each machine, uniformly. Otherwise, any theoretical thing you want to do with main in the STG machine requires that you have an existential quantification of the input of main, so that you can say 'there exists some input i such that main {i} runs to completion'. This formalism doesn't take care of additional arguments, either, and that means that i cannot firmly be a value---it has to be some constructor. So now your machine went from "run main and watch it tick" to "pick some constructor that your main will immediately match on to extract I/O information like the initial arguments, and then apply it as main {C x1 x2 ... xn}". Unfortunately, even that doesn't alleviate the headache that your proofs are all going to look like, "There exists C, x_1, ..., x_n, such that main {C x1 x2 ... xn} [does whatever you're trying to prove]". As a result, and since Haskell was built up from the STG machine, piece by piece, main takes no input and produces no output. Pushing main into the IO monad doesn't break this formalism, because the IO abstractions are just additional functions that live in the global environment of the STG machine as "build-ins" that behave correctly by the time you get down to the STG machine, but rewriting main to explicitly take or return things ruins the underlying abstract model.
|
# ? Jun 4, 2015 02:54 |
|
Cross-posting from the .NET megathread:NihilCredo posted:So if you want to create a WebSharper website, what are your options for good-looking UI controls beside KendoUI?
|
# ? Jun 5, 2015 06:28 |
|
Smoke_Max posted:Hi, Haskell newbie here. I was wondering why main doesn't have a [String] -> IO () type signature like other programming languages, like C/C++ or Java. It would be pretty cool, thanks to pattern matching, to be able to do things like this: Yet another reason is that there is no guarantee that the contents of argv can be coerced meaningfully to a 'String'. It is just a byte-string, after all. True, 'getArgs' will simply assume that the byte-string encodes text in the native encoding, but at least you have a chance to do something different, which would not be the case if the damage had been done before 'main' was even invoked. Also, the 'String' type is horribly and hilariously inefficient and wasteful, so you may not want to use it. As for option parsing, I am old-fashioned, so I just use the default GetOpt module. I never saw the point in the more fancy libraries; it's just option parsing.
|
# ? Jun 5, 2015 10:23 |
|
I talked about Haskell briefly a couple times IRL. Both times people initially thought I was talking about Pascal.
|
# ? Jun 9, 2015 14:52 |
|
comedyblissoption posted:I talked about Haskell briefly a couple times IRL. Are you mispronouncing Haskell like I did for a long time? (Or am I still mispronouncing Pascal?)
|
# ? Jun 9, 2015 15:43 |
|
Hass-kull.
|
# ? Jun 13, 2015 18:57 |
Haskell question: I want to upgrade ghc to 7.10, because a lot of the new stuff looks pretty sweet. What's the best way to do this without breaking everything I've installed with cabal? If that's not possible, what's the best way to fix everything I break? My Haskell installation is the one provided through https://www.haskell.org/platform/, and it's version 2013.2.0.0 if that matters.
|
|
# ? Jun 14, 2015 21:15 |
|
When you update GHC it creates a new cabal tree for the new version. You'll have to reinstall what you need and recompile existing binaries if they depend on runtime linking like Xmonad. I usually keep the old version around for a while.
|
# ? Jun 14, 2015 21:51 |
|
Use cabal sandboxes for all your projects imo.
|
# ? Jun 15, 2015 01:44 |
|
Scheme question, what is the 'right' way to associate a unique function with an instance of a record type? I'm decoding opcodes. The process of decoding which instruction the opcode refers to has a regular structure for which I've defined a record type. My question refers to how to then parse the fields. My current solution is to add a lambda expression to the instance that is responsible for determining if a opcode can be decoded by that instruction and parsing out the fields. code:
code:
code:
code:
|
# ? Jun 18, 2015 16:12 |
|
I've got to say, I've really been loving F# lately. Having access to all of C#'s libraries and documentation, access to visual studio (although F# power tools and github integration is required, and resharper recommended). The only things I miss about Haskell tend to be more little-picture in nature: record ADTs with multiple constructors, hackage's ability to search for type signatures, 'where' blocks. My biggest complaint by far is the single-pass compiling which means that you can't really have forward references but you do kind of get used to it after a while.
|
# ? Jun 18, 2015 17:27 |
|
Barnyard Protein posted:Scheme question, what is the 'right' way to associate a unique function with an instance of a record type? The way you've written this up, I'm not 100% certain what you're exactly trying to do. There isn't enough detail here for me to piece out what make-instructio actually does, and what the procedure it takes is expected to do. Also, why does the lambda take an opcode if it's tied to a particular instance of a particular record? Couldn't it just, you know, know its opcode? I would have expected code that looked like: code:
code:
This approach, is, though, pretty OO-like. I would be was lazier about this, and probably just write something like: code:
QuantumNinja fucked around with this message at 23:00 on Jun 18, 2015 |
# ? Jun 18, 2015 22:50 |
|
Thanks for the response, I think what you're describing in the first part is what I'm doing, but I'm not sure I understand. I'll have to chew on this for a bit. Here's a more complete picture of what I'm doing. Decoding happens in two passes, the first pass find the instruction that returns #t from "is-it-one?", the 2nd pass yanks out the instruction fields. I arrived at this approach because I have an urge to keep all information about an instruction and its decoding in one place, but this doesn't even do that. The a-list returned by opcode->fields is a new object disassociated from the instruction. back to the drawing board! Lisp code:
|
# ? Jun 18, 2015 23:46 |
|
Yes, I'd do this super-different.Lisp code:
At this point, though, you've pretty much rolled your own ghetto free-for-all facsimile of a record inheritance structure, so use the one in your implementation instead if it's there. In R6RS I'm pretty sure it would look about like this: Lisp code:
Lisp code:
The reference is SICP, chapter 4 (it's free online). (Sorry if there are typos in the above code; I did it without a repl or my usual VIM setup because I'm feeling lazy. I hope it gets the ideas across.) EDIT: If there are less than 15 opcodes, I actually wouldn't bother writing add-opcode? and the like. I'd just write to-instr using the bit-operation queries on the left of the cond, leave a comment at each test indicating what it was doing, and dump the input in there before doing anything else with it. And if all of the constructors for the instruction records are as simple at the one in build-new-add-instr, I might not even pull those out if I was never, ever going to build a new instruction anywhere else in the program. If you're worried about recovering the opcodes, I'd write instr->opcode that reverses the process. EDIT2: The procedure you should write and use all over, though, is: Lisp code:
Lisp code:
QuantumNinja fucked around with this message at 01:45 on Jun 19, 2015 |
# ? Jun 19, 2015 01:36 |
|
Is learning Haskell intended to be an order of magnitude more difficult than other programming languages?
|
# ? Jun 19, 2015 03:50 |
|
By design, yes! Mostly, it lacks a good resource for looking up "how do I X" in the language. The wiki book is tolerable, but incomplete. Learn You a Haskell is aimed at people who don't know what a function is, and as far as I can tell Real World Haskell is aimed at C programmers trying to write bar-code scanners in Haskell Edit: the way everyone I know who has learned Haskell has done it by building something large. It turns into "How do I X" and reading Stack Overflow enough times that at the end you know the language.
|
# ? Jun 19, 2015 03:55 |
|
I might try again with another resources. I used LYAH, and it felt more like documentation of every part of the standard library than a tutorial. Something that teaches how to build simple, useful programs using basic features would have been more helpful.
|
# ? Jun 19, 2015 04:01 |
|
RWH felt to me more like ‘make random poo poo’ but does have the enormous problem that it targets a version of everything from beyond the dawn of time, so nothing works any more. Other than that I can't think of any obvious resources. At least to me though, once you know the stuff in LYAH doing things in Haskell isn't all that different to everything else; loving round with REST stuff in Haskell using Wreq isn't hugely different to doing it in anything else. Something that helped a lot of people where I work with Haskell was approaching it via Scala; if you think that'd work for you I guess you could check out Functional Programming in Scala which everyone seemed to like.
|
# ? Jun 19, 2015 05:41 |
|
Dominoes posted:Is learning Haskell intended to be an order of magnitude more difficult than other programming languages? Haskell is probably only a magnitude harder than other programming languages when you're already deeply familiar w/ imperative/OOP programming languages. Usually when picking up a new language you just learn new syntax to do the same drat thing you've always done and can re-apply all of your learned experience in a straightforward manner. You've already learned much of what there is to know about the language by having learned prior languages in the same paradigm. When learning a pure functional language with a non-strict evaluation strategy, you can't just re-apply your learned experience in a straightforward manner and have to a learn a bunch of novel concepts. comedyblissoption fucked around with this message at 06:35 on Jun 19, 2015 |
# ? Jun 19, 2015 06:30 |
|
It basically is designed to be harder to learn than most other programming languages, at least assuming you already know a "normal" programming language. If you know Java and you want to learn C#, you're mostly just going "OK, this is how I do ____ in C#", but with Haskell, you have to learn to approach things from a different direction. e: the guy above me said it better. fart simpson fucked around with this message at 07:04 on Jun 19, 2015 |
# ? Jun 19, 2015 06:46 |
|
There's an inherent difficulty in learning Haskell as an imperative programmer, but it's made much worse by the documentation that's out there.
|
# ? Jun 19, 2015 08:17 |
|
FP complete articles are getting better. This works with any language: Start with a simple target like a TODO list web application. Pick a library like Spock or Servant for web stuff, and a friendly database library. Between that documentation, LYAHFGG, and StackOverflow you should be able to limp by. It will be painful at first, but by the end of it you will feel much less crippled and be ready to stroll around the language more confidently. Edit: Also use stackage and stack https://www.stackage.org/
|
# ? Jun 19, 2015 09:19 |
|
https://github.com/bitemyapp/learnhaskell
|
# ? Jun 19, 2015 09:29 |
|
I actually like "Learn You A Haskell". It starts off nice and slow and doesn't immediately go off into la-la land that make most other Haskell tutorials so off-putting. It was the first thing that I read about Haskell that I could actually follow and made me appreciate the language. This is coming from someone that has been programming for 20+ years in various languages (not that I am any good) of which Common Lisp is my preferred.
|
# ? Jun 19, 2015 10:50 |
|
"Learn You a Haskell" mostly worked for me with a few notable gaps. "Learn You Some Erlang" felt like it took a similar approach but brought me up to speed much more quickly and completely. Possibly because I went into Haskell before Erlang, though.
|
# ? Jun 19, 2015 14:32 |
|
QuantumNinja posted:<<wisdom>> You're awesome, thank you, this is really helpful feedback.
|
# ? Jun 19, 2015 15:43 |
|
Hey dudes, Haskell's complaining that none of my variables are in scope. What's up? It does the same when using where in place of let, or 'a' syntax in the type sig.code:
Dominoes fucked around with this message at 07:11 on Jun 21, 2015 |
# ? Jun 21, 2015 06:53 |
|
I don't know exactly what your error message is, but in Haskell, variables have to start with a lowercase letter. If it starts with an uppercase letter, it's a type, so I'm guessing the compiler is complaining the T, Tc, Pc, etc types are not in scope. Try lowercasing them.
|
# ? Jun 21, 2015 07:29 |
|
That is the problem yeah, but not quite the right explanation - types and values are in different namespaces. The two can never be confused as there's never a place in the syntax which could accept either a type name or a value name (at least without wacky extensions). Dominoes, the rules are that: Values: - Start with uppercase = constructor for a datatype (have to be defined with 'data' or 'newtype', and after the '='). - Start with lowercase = normal value that you define with 'where', 'let', or is a top-level function in a module. Types: - Start with uppercase = an actual definite (called concrete) type, defined with 'data', 'newtype' or 'type', before the '='. - Start with lowercase = a type variable, can turn out to be any concrete type (or you can constrain it using typeclasses and '=>'). e: I ran some similar code and got the error "Not in scope: data constructor 'Butt'". Can you see now why it gives that error? You can't define new data constructors on the fly in 'where' or 'let' blocks (but you CAN pattern match on existing ones there which is why it's not a syntax error). gonadic io fucked around with this message at 07:49 on Jun 21, 2015 |
# ? Jun 21, 2015 07:47 |
|
Oh yeah sorry, I felt like there was something wrong with my description.
|
# ? Jun 21, 2015 07:50 |
|
|
# ? May 2, 2024 23:44 |
|
Thank you for the detailed explanation. It makes sense, and solves the issue I posted. I'm running into a second issue with the code I posted above, after fixing the variable names:quote:No instance for (Integral Float) arising from a use of `^' The nature of the error changes a bit if I change the type signature, but I can't sort it out. It's specifically pointing to my variable e. Note that this is a variable defined within the let, while the type signature should, AFAIK, just deal with input and output variables, which are both floats. Dominoes fucked around with this message at 08:27 on Jun 21, 2015 |
# ? Jun 21, 2015 08:17 |