<FromGitter>
<Blacksmoke16> would yield a string and return an int32
<FromGitter>
<smalls12> ok
<FromGitter>
<tenebrousedge> generally, you *must* specify the return type of a proc
<FromGitter>
<smalls12> and inside the proc, explicitly saying ```return 0``` is 'allowed' right ?
<FromGitter>
<tenebrousedge> try not to do that
<FromGitter>
<smalls12> I wasn't specifying the return type before in the function signature, but using return 0 to allow the compiler to just figure it out
<FromGitter>
<smalls12> and this worked
<FromGitter>
<smalls12> however, ameba analysis complained at me
<FromGitter>
<Blacksmoke16> prob since the `return` keyword was redundent
<FromGitter>
<smalls12> that was the error it returned, however this isn't really an error, its just unneccessary
<FromGitter>
<Blacksmoke16> right
<FromGitter>
<smalls12> fair enough, I conformed to what ameba says anyways : )
<FromGitter>
<Blacksmoke16> guess ill have to go the inheritance route for this one.
<FromGitter>
<tenebrousedge> D:
postmodern has joined #crystal-lang
Munto has joined #crystal-lang
Munto has left #crystal-lang ["Leaving"]
<FromGitter>
<tenebrousedge> @Blacksmoke16 I think it's intended. The class you're referencing is `Foo:Module`. You want a class that's comparative with that rather than exactly equal
<FromGitter>
<tenebrousedge> can you pass an instance of `MyClass` and get the type info from that?
<FromGitter>
<Blacksmoke16> naw, i just switched to parent class
<FromGitter>
<tenebrousedge> <_<
<FromGitter>
<tenebrousedge> inheritance is ew
<FromGitter>
<Blacksmoke16> eh for this context its not bad
<FromGitter>
<Blacksmoke16> essentially just used as an interface
<FromGitter>
<tenebrousedge> pretty sure that GoF said, "inheritance is always super bad, never use it"
<FromGitter>
<Blacksmoke16> *lies*
<FromGitter>
<tenebrousedge> 😁
<FromGitter>
<andrewc910> Why would you say inheritance is bad?
<Nilium>
Trying to figure out where it is so I can just go "this error is wrong"
<Nilium>
Found it.
<FromGitter>
<tenebrousedge> k
<FromGitter>
<tenebrousedge> what's the code that's throwing that, or do you have a handle on it?
<Nilium>
It's a dumb experiment in writing OK/Error types. The code's almost definitely wrong, but still poking at it. I'll throw it in a gist in a second.
<Nilium>
Also confirmed the code was incorrect, so the compiler wasn't wrong, in any case.
<FromGitter>
<bew> @asterite hey! I don't understand the last example with Pointer(Foo), why does it compile in this case?
<FromGitter>
<bew> hmm no nvm, but isn't there a way to check for that case anyway?
<FromGitter>
<alexherbo2> Hi
<FromGitter>
<alexherbo2> How to write de generic class, taking a type; I want to create a library to manipulate tree data stuctures, where `value` is configurable.
<FromGitter>
<alexherbo2> and also, what is the difference between `app` and `lib` when initializing a new project?
<FromGitter>
<asterite> @bew I don't think it matters, it's just a made up example
<FromGitter>
<asterite> I would avoid subclasses where generic types are involved
<FromGitter>
<asterite> I'd use generics like this: `class Foo(T)`. That's it. Never include a module in them and use that as an instance var. Never have them have a superclass and use that as an instance var.
<FromGitter>
<asterite> It's pretty limited, but the compiler is built without those things, so I think anything is possible to do
<FromGitter>
<Blacksmoke16> which is essentially used to be like "this action has an argument and heres some metadata about it to try and resolve that argument from a request"
<FromGitter>
<Blacksmoke16> maybe a privet method `private def set_flash(user)`?
<FromGitter>
<Blacksmoke16> oops wrong ch
<FromGitter>
<asterite> I think it can be fixed, I just don't know how right now
<FromGitter>
<Blacksmoke16> if anyone can do it, it's you :p
<FromGitter>
<stronny> I'm a bit sceptical on the logic side here looking at your reduced example: you seem to use Param as a hack around the type system
<FromGitter>
<stronny> if you declare Array(Param) you may only use what Param provides, in your case nothing
<FromGitter>
<Blacksmoke16> it doesnt make a difference if you add abstract defs or not, so i just dont bother
<FromGitter>
<stronny> how do you type your abstract defs?
<FromGitter>
<stronny> what are you gonna do with instances of your array? the should have at least one method with a common signature
<FromGitter>
<asterite> @stronny that's the thing. The type system doesn't let you have an instance variable of type `Foo` where `Foo` is `Foo(T)`. However, if you include a module into `Foo`, now that module includes every generic instantiation of `Foo(T)`, which is something the type system didn't support in the beginning. I added hacks and hacks to make it work, but they never seem to be enough. Something radical has to change in
<FromGitter>
... the type system or the compiler to implement it "right"
<FromGitter>
<Blacksmoke16> should be able to have an array of `Foo` regardless of the generic value of each specific instance
<FromGitter>
<stronny> Foo(T1) and Foo(T2) are two unrelated types
<FromGitter>
<stronny> maybe the generic syntax confuses people
<FromGitter>
<Blacksmoke16> they're kinda related in my use case, would still be an argument, just with different types for the value/default
<FromGitter>
<stronny> if they are related, express that in terms of the language and everything would work
<FromGitter>
<Blacksmoke16> right thats the issue, idt there's a way to do that right now?
<FromGitter>
<asterite> > should be able to have an array of `Foo` regardless of the generic value of each specific instance ⏎ No other language can do that. Generics exists in C# and Java and you can't do that. If you do that in Java it's just `Object` but you lose type safety.
<FromGitter>
<asterite> Quoting works really bad in gitter...
<FromGitter>
<stronny> what are the common methods that these structs share?
<FromGitter>
<asterite> well, I think that's fine. Sometimes you can't express everything that generically and you need to escape the type system. Otherwise, yes, you can always do it but it's a bit more tedious or hacky
<FromGitter>
<stronny> common means `exactly same signature`
<FromGitter>
<stronny> Haskell bois live without an escape hatch afaik
<FromGitter>
<asterite> What is the T in ArgumentMetadataBase? Can it not be a generic type and instead replace T with all the values it supports?
<FromGitter>
<asterite> @stronny exactly. Haskell is very strict, they don't even have something like Object or inheritance, and everything can be done there
<FromGitter>
<asterite> they do have typeclasses, though, which are similar to interfaces
<FromGitter>
<Blacksmoke16> @asterite `T` represents the type restriction of a method argument
<FromGitter>
<Blacksmoke16> e.x. `def get_request_path(id : Int32) : Int32`, would have an metadata instance like `ArgumentMetadata(Int32).new("id", false, false, nil)`
<FromGitter>
<asterite> Why does that need to exist at runtime?
<FromGitter>
<Blacksmoke16> because a request happens at runtime, which may or may not include a value for a specific argument. If it doesnt i needed a way to return the default that was defined on the method
<FromGitter>
<stronny> how many different types can values have?
<FromGitter>
<stronny> you may build that somewhat similar to JSON::Any
<FromGitter>
<stronny> why do converters have to live in the common area? you don't have user-defined types at the routing stage, because HTTP is text, maybe users can have the converters at the controller?
<FromGitter>
<Blacksmoke16> mainly so the logic could be centralized and reused
<FromGitter>
<stronny> if it works that means you are bypassing typechecks
<FromGitter>
<Blacksmoke16> not quite, it'll still fail to compile if a converter converts the value into the wrong type
<FromGitter>
<Blacksmoke16> er, at least be handled gracefully
sz0 has quit [Quit: Connection closed for inactivity]
<FromGitter>
<stronny> at this point I can't really say anything without diving in your code
<FromGitter>
<stronny> in my experience Crystal allows a rather wide gray area that makes sense to a human, but isn't provable by typechecks. It works fine until is stops and then you're in for a lot of FUN
<FromGitter>
<stronny> on a much higher level I wouldn't ever build a webapp using Crystal at all
<FromGitter>
<tenebrousedge> o_________o
<FromGitter>
<tenebrousedge> wat
<FromGitter>
<stronny> yeah
postmodern has quit [Quit: Leaving]
<FromGitter>
<tenebrousedge> "Are you like, a crazy person?"
teardown has quit [Ping timeout: 258 seconds]
<FromGitter>
<Blacksmoke16> my assumption/point of view atm is there is only so much type safety you can have at compile time in a web framework, just due to a lot of it being tied to what request comes in at runtime
<FromGitter>
<Blacksmoke16> im prob sacrificing *some* type safety for flexibility
<FromGitter>
<Blacksmoke16> looks like something is doing `num / 0`?
<FromGitter>
<manveru> hmm, i just fixed it by removing the corresponding directory in ~/.cache/crystal
<FromGitter>
<manveru> very weird
<FromGitter>
<nilium> I have to blow those away pretty frequently.
<FromGitter>
<manveru> i think it might be because i used watchexec, which might have killed crytal during compilation, leaving some invalid cache entries?
<FromGitter>
<nilium> Yeah. Same with entr for me.
<FromGitter>
<nilium> Crystal doesn't lock its cache or recover from bad caches, so it just kind of explodes sometimes.
<FromGitter>
<manveru> good to know...
<FromGitter>
<nilium> From what I can tell, you can get a similar effect just by running a build a few times in parallel from the same dir
<FromGitter>
<nilium> Don't know why you'd do that but I did out of morbid curiosity.
<FromGitter>
<tenebrousedge> is nilium the element from which `Nil`s are forged?
<FromGitter>
<nilium> Apparently it's a window cleaner.
<FromGitter>
<nilium> Or deodorizer? I don't know. I'm apparently very flexible when it comes to cleaning.