Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Dylan16807
May 12, 2010

they effect slowdown

Adbot
ADBOT LOVES YOU

VikingofRock
Aug 24, 2008




Could someone explain that tef post to someone who doesn't know any ruby whatsoever?

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

tef posted:

nil turns a lookup into a lexical lookup.

code:
A = "butt"
module Butt
  B = nil
  puts B::A
end

I thought modules had their own namespace, and "FOO = nil" wouldn't interact with it. gently caress.

I've written 0 lines of Ruby.

triple sulk
Sep 17, 2014



VikingofRock posted:

Could someone explain that tef post to someone who doesn't know any ruby whatsoever?

ruby is bad

tef
May 30, 2004

-> some l-system crap ->

VikingofRock posted:

Could someone explain that tef post to someone who doesn't know any ruby whatsoever?

yes, but if you're asking me then i'll have to explain to you how ruby works.

well, explain my current understanding of how ruby works. i'm never really sure if i've reached the bottom of the rabbit hole.

let's open with one description of ruby http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/179642?matzlisp

Matz posted:

Ruby is a language designed in the following steps:

* take a simple lisp language (like one prior to CL).
* remove macros, s-expression.
* add simple object system (much simpler than CLOS).
* add blocks, inspired by higher order functions.
* add methods found in Smalltalk.
* add functionality found in Perl (in OO way).

So, Ruby was a Lisp originally, in theory.
Let's call it MatzLisp from now on. ;-)

so ruby is a lisp, an object system, methods, blocks, and perl syntax. let's skip the lisp and start with the objects:

irb(main):012:0> Object
=> Object

Modules and Classes are two types of Object in ruby, both used to build other objects.

irb(main):001:0> module A
irb(main):002:1> end
=> nil
irb(main):008:0> class B
irb(main):009:1> end

Modules and Classes both can contain methods, but classes can be instantiated to produce instances.

irb(main):010:0> A.class
=> Module
irb(main):011:0> B.class
=> Class
irb(main):005:0> Module.class
=> Class
irb(main):006:0> Class.class
=> Class
irb(main):007:0> Object.class
=> Class

We see that A is an instance of Module, and B is an instance of a class. We can also see that Module, Class, and Object are all instances of the Class object.

irb(main):003:0> A
=> A

What is A? A is a module. Well, A is actually a Constant. A special variable that is bound to a value, which in this instance is an object,
which is an instance of Module. Got that? Constants are variables which are looked up in a special way:

When we ask what is A, we look at the current module/class scope and check for a constant named A, and proceed up.

irb(main):025:0> module A
irb(main):026:1> module B
irb(main):027:2> end
irb(main):028:1> end

irb(main):029:0> A::B
=> A::B

we can use :: to look up the constant B inside the object pointed to by the constant A. What happens when we do A is that we're doing nil::A implicitly.

irb(main):031:0> A
=> A
irb(main):032:0> nil::A
=> A

when you write A::B::C in ruby, it is parsed as (A::B)::C for , so if A::B resolves to nil, the entire expression is just nil::C. nil just means "the current module scope".

irb(main):044:0> module A
irb(main):045:1> puts B
irb(main):046:1> end
A::B
=> nil

irb(main):048:0> module A
irb(main):049:1> puts nil::B
irb(main):050:1> end
A::B
=> nil

the current module scope is lexical

irb(main):004:0> module A
irb(main):005:1> Z = 2
irb(main):006:1> module B
irb(main):007:2> Z = 3
irb(main):008:2> puts Z
irb(main):009:2> end
irb(main):010:1> puts Z
irb(main):011:1> end
3
2
=> nil
irb(main):012:0> puts Z
1
=> nil

but remember, if you do module A::B, it is not the same as doing module A; module B. in ruby, the former adds "A::B" to the search scope, and the latter adds "A", "A::B" to the scope. it isn't syntactic sugar, it's a whole different mechanism.

here we have A::B::Z, A::Z and Z. but where does A::B::Z and A::Z and Z live? Object of course!

irb(main):038:0> Object::A
=> A
irb(main):039:0> Object::A::B
=> A::B

indeed, all of the built in classes in ruby are listed as constants under object

irb(main):040:0> Object::String
=> String
irb(main):041:0> Object::Kernel
=> Kernel
irb(main):042:0> Object::Class
=> Class
irb(main):043:0> Object::Module
=> Module

when you do X = 1 in ruby, you're actually setting Object::X to 1.when you define module Router, you're defining module Object::Router.
every class and module, and method definition at the top level is in someway monkeypatching Object.




but enough about objects, let's look at methods. then we'll get onto blocks, and the syntax.



to do anything in ruby, you send a message to an object, or call a method

rb(main):003:0> [1,2,3].send(:max)
=> 3
irb(main):004:0> [1,2,3].max
=> 3

these messages live in a different namespace to constants. you can have a class with a method X and a constant Y.

irb(main):006:0> class X
irb(main):007:1> Y = 1
irb(main):008:1> end

irb(main):010:0> def X.Y # define a class method Y
irb(main):011:1> 2
irb(main):012:1> end
=> :Y
irb(main):013:0> X::Y # look up the constant
=> 1
irb(main):014:0> X.Y # look up the method 'Y'
=> 2

but, confusingly, :: can also be used to call methods

irb(main):026:0> "123".size
=> 3
irb(main):027:0> "123"::size
=> 3

the :: operator takes the right hand argument as a literal token, and if the first letter is uppercase, it's a constant, if the first letter is lowercase, it's a method lookup.

constants *must* start with an uppercase letter. method names on the other hand don't care, because they are symbols.

irb(main):040:0> "123".send(:size)
=> 3

what's that :size? it's a symbol, another type of object.

irb(main):041:0> :size
=> :size
irb(main):042:0> :size.class
=> Symbol

if constants are special variables that start with a capital letter, symbols are special values. they're kinda like immutable strings, and used inside
objects to define which methods to invoke. method names are even stricter than constants.

irb(main):054:0> :"foo!o"
=> :"foo!o"
irb(main):055:0> def foo!o
irb(main):056:1> end
=> :foo!
irb(main):057:0> foo! 1
=> nil

here, the method name is parsed as foo! and the parameter o. method names cannot have spaces, can have underscores, and can end in ? or !.

well, almost. it turns out you can define any method you like, even nulls. you just can't use anything other than send to invoke it:

irb(main):049:0> define_method(:"foo\0bar") do |x| x*2 end
=> :"foo\x00bar"
irb(main):050:0> send(:"foo\0bar", 1)
=> 2

anyway, i'm getting ahead of myself. when you define a method on an object, you can define it on one of two namespaces,
the class namespace, and the instance namespace.

irb(main):001:0> class Foo

irb(main):002:1> def self.cls_method
irb(main):003:2> "class"
irb(main):004:2> end

irb(main):005:1> def inst_method
irb(main):006:2> "instance"
irb(main):007:2> end

irb(main):008:1> end

irb(main):009:0> Foo.cls_method
=> "class"
irb(main):010:0> Foo.new.inst_method
=> "instance"

they are in totally different namespaces: you can't call cls_method on a Foo instance.

irb(main):011:0> Foo.new.cls_method
NoMethodError: undefined method `cls_method' for #<Foo:0x007f9022891958>

[if you're keeping count, an object has three namespaces so far: class methods, instance methods, constants]

and as you'd expect for class methods, they're inherited.

irb(main):012:0> class Bar < Foo
irb(main):013:1> end
=> nil
irb(main):014:0> Bar.cls_method
=> "class"
irb(main):015:0> Bar.new.inst_method
=> "instance"

methods are public by default. this means any other object can call that method. protected methods cannot be invoked
outside of subclasses, and private methods cannot be invoked outside of the instance. so a private class method cannot be called by an instance method, and vice versa.

speaking of private methods: have you ever wondered how "puts" works in ruby?

irb(main):001:0> puts "butts"
butts
=> nil
irb(main):002:0> "butts".puts
NoMethodError: private method `puts' called for "butts":String

puts is a private method, so we can't call it normally. we can cheat and use send:

irb(main):003:0> "butts".send(:puts)

=> nil

ok, what's happening here. we sent puts to butts but nothing happened

irb(main):004:0> Object.send(:puts, "butts")
butts
=> nil

puts is a private method on object. string inherits from object and thus has puts.

thus we can override it:

irb(main):010:0> class Test
irb(main):011:1> def inst
irb(main):012:2> puts "inst"
irb(main):013:2> end
irb(main):014:1> def self.cls
irb(main):015:2> puts "class"
irb(main):016:2> end
irb(main):017:1> end

irb(main):018:0> Test.cls
class
=> nil

irb(main):019:0> Test.new.inst
inst
=> nil

we can define a class method puts:

irb(main):026:0> class Test
irb(main):027:1> def self.puts x
irb(main):028:2> "ha ha"
irb(main):029:2> end
irb(main):030:1> end
=> :puts
irb(main):031:0> Test.cls
=> "ha ha"
irb(main):032:0> Test.new.inst
inst
=> nil

and we can define a instance method puts.

irb(main):033:0> class Test
irb(main):034:1> def puts x
irb(main):035:2> "lol"
irb(main):036:2> end
irb(main):037:1> end
=> :puts
irb(main):038:0> Test.cls
=> "ha ha"
irb(main):039:0> Test.new.inst
=> "lol"

when you puts "Hello world" in ruby, you're invoking either a private method on Object's class methods or a private method on Object's instance methods (or any subclass in between that defined puts). this is why Object has so many built in methods:

irb(main):002:0> Object.methods.size
=> 100

(this value changes between versions of ruby. don't expect it to match.)

modules also have two namespaces for class and instance methods. unlike class inheritance, when you `import` a Module you copy the instance methods + constants,
and when you `extend` you import the class methods and constants. this leads to funny ways to define class methods:

irb(main):028:0> module Dave
irb(main):029:1> extend self
irb(main):030:1> def hi
irb(main):031:2> "hello"
irb(main):032:2> end
irb(main):033:1> end
=> :hi
irb(main):034:0> Dave.hi
=> "hello"

there's magic in ruby to make sure this works, even when you haven't defined the methods yet. as well as other tricks
to define class methods that would make bjarne stroustrop jealous:

irb(main):040:0> class Helper
irb(main):041:1> end
=> nil
irb(main):042:0> class << Helper
irb(main):043:1> def help
irb(main):044:2> "no"
irb(main):045:2> end
irb(main):046:1> end
=> :help
irb(main):047:0> Helper.help
=> "no"

irb(main):048:0> def Helper.wat
irb(main):049:1> "mate"
irb(main):050:1> end
=> :wat
irb(main):051:0> Helper.wat
=> "mate"

thing is, you can define methods on instances like this, to define per-instance methods, rather than per-classmethods.

irb(main):054:0> d = Dog.new
=> #<Dog:0x007fc8638c74f8>
irb(main):055:0> def d.wag
irb(main):056:1> "bow wow"
irb(main):057:1> end

irb(main):060:0> class << d
irb(main):061:1> def sit
irb(main):062:2> "good dog"
irb(main):063:2> end
irb(main):064:1> end
=> :sit
irb(main):065:0> d.sit
=> "good dog"

when i said there were two namespaces on a class, it would be more accurate to say that there's two classes behind the scenes,
the normal class, which contains instance methods, a hidden class, which contains class methods

when you're defining class methods in ruby on a module or class, you're actually defining methods on a hidden eigenclass
for the class or module. for subclasses, they have a hidden eigenclass, which inherits from the parent's eigenclass.
for modules, include/extend copy from the class or hidden class.

the hidden class is often called an eigenclass, and class methods are often called singleton methods. remembering
that constant scope is lexical, you can sorta set one off constants inside instances

code:
class Timer
  TIMEOUT = 100

  def self.timeout
    TIMEOUT
  end

  def timeout
    TIMEOUT
  end
end

t = Timer.new
puts "Timer.timeout = #{Timer.timeout}" # 100
puts "t.timeout = #{t.timeout}" # 100

class << t
  TIMEOUT = 200 # won't change timeout because the one in foo is lexical.
end

puts "Timer.timeout = #{Timer.timeout}" # 100
puts "t.timeout = #{t.timeout}" # 100

class << t
  def timeout
    TIMEOUT # now it picks up the new value.
  end
end

puts "Timer.timeout = #{Timer.timeout}" # 100
puts "t.timeout = #{t.timeout}" # 200

puts "Timer::TIMEOUT = #{Timer::TIMEOUT}" # Now 200
but i guess it's easier to think of objects having constants, instance methods, and class methods, over
class or module objects having two classes behind the scenes both with modules and methods.

still, you'll should notice i'm not redefining TIMEOUT, but defining a new TIMEOUT inside a hidden class on an instance.

(fwiw you can reassign constants, and you can define constants in modules or classes, but not
method definitions (but you can define constants in blocks if the blocks are defined within a module or class))

i guess it's time to complain about blocks.




blocks.

ugh


if we go back to objects and sending a message, we can think of the class or instance methods as being stored in a lookup table.
if the key is a symbol, then the value in the table is a block.

a block in ruby is a piece of code captured inside do ... end or {|x| .... } blocks, and can take parameters. they're lexically scoped,
and refer to the environment in which they live.

irb(main):013:0> y = 1
=> 1
irb(main):014:0> x = the_block do y = 2 end
=> #<Proc:0x007fa78c865660@(irb):14>
irb(main):015:0> x.call
=> 2
irb(main):016:0> y
=> 2

as i mentioned earlier, it's just a lump of code that refers to its enclosing scope, so what you do in the scope, you can do in the block

irb(main):017:0> x = the_block do CONST = 2 end
=> #<Proc:0x007fa78c84c458@(irb):17>
irb(main):018:0> x.call
=> 2

since I can assign Constants at the top level, I can do it inside the block too. this is often referred to as the "Tennent's Correspondence Principle",
or as i call it, the "blocks are not functions" principle.

irb(main):019:0> def foo
irb(main):020:1> x = the_block do return "ha ha" end
irb(main):021:1> x.call
irb(main):022:1> return "nice"
irb(main):023:1> end
=> :foo
irb(main):024:0> foo
=> "ha ha"

When you call return inside a block, it returns from the method invoking x.call itself, not from x.call.

in ruby, returns in blocks work like exceptions in that they can be non-local exits.

but when i say block, i really mean proc. a block is not a value in ruby, you cannot assign a block to a value,
you have to lift the block into a Proc.

calling the_block is the same as calling proc_new.

irb(main):034:0> def test
irb(main):035:1> p = Proc.new do return "butts" end
irb(main):036:1> call_a_proc p
irb(main):037:1> end

irb(main):038:0> test
=> "butts"

which is why when you call a proc with a return, from the top level scope, well, heh.

irb(main):031:0> p = Proc.new { return "ha" }
=> #<Proc:0x007fa78c038730@(irb):31>
irb(main):032:0> call_a_proc p
LocalJumpError: unexpected return

but you can make return work like you expect it to by wrapping blocks inside lambda.

irb(main):050:0> p = lambda do return 1 end
=> #<Proc:0x007fa78c884a38@(irb):50 (lambda)>
irb(main):051:0> call_a_proc p
=> "done"

you can use next in blocks to emulate return in lambdas. i think

atop of blocks, procs, and lambdas, you also have method objects

irb(main):054:0> "123".method(:size).call
=> 3

and unbound method objects, which you need to bind to an object to call. this works because blocks
have no real notion of self:

irb(main):052:0> p = Proc.new do self end
=> #<Proc:0x007fa78c8649e0@(irb):52>
irb(main):053:0> p.call
=> main

irb(main):059:0> p = lambda do self end
=> #<Proc:0x007fa78c05b4d8@(irb):59 (lambda)>
irb(main):060:0> p.call
=> main

self is dynamically scoped and overriden at runtime for lambdas, and blocks, and procs

irb(main):014:0> Foo.new.foo
=> #<Foo:0x007fc49286d0b8>
irb(main):015:0> Foo.new.method(:foo).call
=> #<Foo:0x007fc492864008>

but when you capture a method, you bind self. you can unbind it, but you must rebind the method
to an instance of the class it came from. var that = this has nothing on this mess.

on the plus side, whenever you do foo.call it might return from your method, it might throw a non local
return error, and maybe it will know what self is.

the whole point of having blocks is so you can do non local returns but in practice no-one uses them much.

i guess i'm on the final stretch of complaining now, so i guess it's time for the features from perl.


the syntax.

on the whole, perl gets a bad rap for many things but it does not take so many words to explain how the object system works. "You're attach a package namespace to a value and when you call a method, it calls the function in the package scope". perl also had modules. ruby has require. even javascript has module loading. ruby has string concatenation.

in the year of our lord 2015 i am still writing a program and building it by pretending it's one gigantic source file.


the syntax of ruby is a whole different beast. whitespace matters deeply in ruby when using the special "method_name args,with,no,parenthesis" syntax.

puts ([1]).map {|x| x+1}
puts([1]).map {|x| x+1}.

the other great feature of no-parenthesis method calls is that you can make things that look like built in operators:

foo "fooo" do

end

unfortunately, it's a little easy to forget the do block, or accidentally put a do block atop a built in construct, and then get a missing 'end' error. or my favourite, that elif is not a syntax error but a runtime one. even perl wasn't this clumsy.


so now you've got the basics of how ruby works, you can understand the code i posted, hope this helps.


1. ruby is bad
2. bad bad bad
3. the end



oh wait, i forgot to mention everything returns the most unhelpful value by default.

irb(main):020:0> [1,2,3].sample(4)
=> [1, 3, 2]
irb(main):021:0> [1][200]
=> nil
irb(main):022:0> {}[:butts]
=> nil
irb(main):023:0> "123 aa".to_i
=> 123
irb(main):024:0> "aa 123 aa".to_i
=> 0

oh and on namespaces, i guess i lost count, but there are also instance variables, which exist on the class and the eigenclass, or if you will, the instance and the class. and class variables too, which unlike instance variables aren't nil by default, and in some ways even harder to explain than eigenclasses.

see also:

http://thoughts.codegram.com/understanding-class-instance-variables-in-ruby/
http://madebydna.com/all/code/2011/06/24/eigenclasses-demystified.html

Typical Yosposter
Mar 30, 2015
https://www.youtube.com/watch?v=jLKnCeeAW48

tef
May 30, 2004

-> some l-system crap ->

it would have saved me a lot of time if you'd posted this a couple of hours ago

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

while you're at it can you explain the funny @foo syntax -- i think it's just a fancy dynamic way to reference a class scope, but i've never been sure

leftist heap
Feb 28, 2013

Fun Shoe
what you're saying is that ruby is actually nothing like lisp and matz is retarded

VikingofRock
Aug 24, 2008




Holy poo poo tef that was one hell of an effort post. Thanks for the write up. :cheers:

tef
May 30, 2004

-> some l-system crap ->
fwiw i've just found out that nil::X and ::X are not the same thing.

triple sulk
Sep 17, 2014



nil is the bane of every ruby programmer (aside from having to use ruby itself)

tef
May 30, 2004

-> some l-system crap ->

Suspicious Dish posted:

while you're at it can you explain the funny @foo syntax -- i think it's just a fancy dynamic way to reference a class scope, but i've never been sure

@foo means the instance variable.

inside a class method it means the class instance (or eigenclass for the class)
inside a normal method it means the instance itself.

these are late bound, and return nil if there is nothing set.

code:
class Foo
 @foo = 1
 def self.foo
   @foo
 end
 def foo
   @foo
 end
 def set_foo x
   @foo = x
 end
 def self.set_foo x
   @foo = x
 end
end
irb(main):059:0> Foo.foo
=> 1

the @foo = 1 sets the @foo inside the object Foo

irb(main):060:0> Foo.set_foo 5
=> 5
irb(main):061:0> Foo.foo
=> 5

the self.foo/self.set_foo methods on Foo operate on the @foo bound to the object Foo

irb(main):063:0> x = Foo.new
=> #<Foo:0x007fc492844848>
irb(main):064:0> x.foo
=> nil

attrs are nil by default, and the instance of Foo does not inherit the value of @foo set in
the object Foo

irb(main):068:0> x.set_foo 9
=> 9
irb(main):069:0> x.foo
=> 9
irb(main):070:0> Foo.foo
=> 5
irb(main):071:0>

so, @foo means "in the current object", which is either the instance of Foo, x, or the class Foo.

irb(main):075:0> class << x
irb(main):076:1> @foo = 9
irb(main):077:1> end
=> 9
irb(main):078:0> x.foo
=> 9

for singleton methods on instances, it refers to the instance, just like singleton methods (class methods)
on classes refer to the class itself.

if you subclassed Foo, the subclass would have it's on @foo, and any instance would too.

if you want to define a vaiable accessible from any subclass, you use a @@foo class variable.

but they work quite differently to @foo.

when you do @@foo = 1, it's as if you're assigning to a constant inside that class or module.
any subclass can also see @@foo, superclasses can't see it.

so class variables are like constants but you can change them without cheating

but if you define a class variable in a module, it means "inside this module" not "inside the class i am bound to"

constants have the same issue, but you don't normally change them, and constants are copied over when including modules.

edit; well almost. heh

tef fucked around with this message at 07:52 on Oct 16, 2015

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

tef posted:

variables are like constants but you can change them

the ruby has gotten to you

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today
So he took a version of Lisp from before most of the really cool features had been developed, removed the cool features that were left, then added back in screwy half-usable square wheel reinventions of everything?

:psyduck:

tef
May 30, 2004

-> some l-system crap ->

Ralith posted:

So he took a version of Lisp from before most of the really cool features had been developed, removed the cool features that were left, then added back in screwy half-usable square wheel reinventions of everything?

:psyduck:

lisp doesn't have any cool features but it comes with a cool features toolkit, where you can write your own ad-hoc, underspecified, never documented, control flow structures

tef
May 30, 2004

-> some l-system crap ->

Suspicious Dish posted:

the ruby has gotten to you

ha ha i lied you can change constants

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

tef posted:

lisp doesn't have any cool features but it comes with a cool features toolkit, where you can write your own ad-hoc, underspecified, never documented, control flow structures
I'll take CLOS over what you just laid out any day

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope
so am i to understand that ruby is the new hipste?

karms
Jan 22, 2006

by Nyc_Tattoo
Yam Slacker
I wonder what dhh thinks of this

prob. "this is great!!"

Cybernetic Vermin
Apr 18, 2005

tef posted:

lisp doesn't have any cool features but it comes with a cool features toolkit, where you can write your own ad-hoc, underspecified, never documented, control flow structures

the main nicety of cl is that the library is both sane and comprehensive

scheme is really neat, but it is fantastically unfortunate in timing, because the usual false ideal of purity ended up running the far more sensible cl out of town, and both died unloved

Sagacity
May 2, 2003
Hopefully my epitaph will be funnier than my custom title.

KARMA! posted:

I wonder what dhh thinks of this

prob. "this is great!!"
he'll just rewrite his fancy todo-list application every three years so he don't care

prefect
Sep 11, 2001

No one, Woodhouse.
No one.




Dead Man’s Band

tef posted:

every single feature rubyists tout as being magical, the quirks that make it pleasant to write a dsl for your boilerplate, and the shorthand that lets your example fit neatly on a slide, well, they have a downside.

code:
if nil
  puts "nil"
elif true
  puts "true"
else
  puts "else"
end
yes of course this prints else.

did you explain this in your big effortpost? (i'm going to read it; I've saved a copy for later, when i have a big block of uninterrupted time. also, thanks so much, because i'm now in a land where it's all puppet and ruby)

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder
I've been working on a ruby library and it's really great how I'll be deep inside my own code and still have no idea what sorts of arguments might get passed into my poo poo.

I've reached a point where all of my methods take a single array and a block, because this is much easier than having, you know, actual arguments

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder
also I just found out that ruby lets you use a hash as the key to a hash. which i guess would be workable in a language with mostly primitive data types. unfortunately ruby does not have any primitive data types.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

tef posted:

lisp doesn't have any cool features

restarts are pretty neat, and the numeric promotion Just Works™ a great deal of the time

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

MALE SHOEGAZE posted:

also I just found out that ruby lets you use a hash as the key to a hash. which i guess would be workable in a language with mostly primitive data types. unfortunately ruby does not have any primitive data types.

i think you'll find that the more you dive into ruby the more hash is involved

Stringent
Dec 22, 2004


image text goes here

Blotto Skorzany posted:

i think you'll find that the more you dive into ruby the more hash is involved

if only

Ralith
Jan 12, 2011

I see a ship in the harbor
I can and shall obey
But if it wasn't for your misfortune
I'd be a heavenly person today

Cybernetic Vermin posted:

the main nicety of cl is that the library is both sane and comprehensive

scheme is really neat, but it is fantastically unfortunate in timing, because the usual false ideal of purity ended up running the far more sensible cl out of town, and both died unloved
I don't know any schemes that actually enforce purity, they just encourage it, which I think even the mainstream is beginning to acknowledge is a good idea.

Racket's pretty neat and about as batteries-included as it gets. There's even Typed Racket, which is surprisingly successful at letting you statically type-check idiomatic Lisp code.

gonadic io
Feb 16, 2011

>>=
haskell seems to be on the verge of a python 2/3 split.

the pressing issue that's got people so riled up on both sides: making the standard library more elegant and less intuitive

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum
awesome post tef, I never quite realized how crazy ruby is but drat

triple sulk
Sep 17, 2014



ruby is insanely bad and anyone left working on rails apps in 2015 suffers from extreme stockholm syndrome

VikingofRock
Aug 24, 2008




gonadic io posted:

haskell seems to be on the verge of a python 2/3 split.

the pressing issue that's got people so riled up on both sides: making the standard library more elegant and less intuitive

I'm assuming you are talking about the Burning Bridges Proposal here? If you feel like typing up some words on this I'd love to read them. I haven't made up my mind on it yet.

JawnV6
Jul 4, 2004

So hot ...
"elegant" is up there with "robust"

gonadic io
Feb 16, 2011

>>=

VikingofRock posted:

I'm assuming you are talking about the Burning Bridges Proposal here? If you feel like typing up some words on this I'd love to read them. I haven't made up my mind on it yet.

it started with the burning bridges proposal, but has since gotten worse (with people currently discussing getting rid of 'return' in favour of just using 'pure' since it's the same thing anyway)

as i understand it, trying to be unbiased: the standard library is based on old haskell (haskell98) and the haskell that's idiomatic (in libraries, applications, modern tutorials, etc etc) is actually quite different. the use of Control.Applicative and Control.Monad is now pretty much universal, not to mention Traversable etc.

there's a current push by the language committee to fix this, to modernise things and apply the lessons learned in the last 20 years.

however many of these are
1) non-backwards compatible (and would invalidate all the old teaching material),
2) are less intuitive and harder for newbies to understand, and
3) don't even really make that much difference other than requiring a little less boilerplate (don't have to import control.applicative and control.monad everywhere)

so it's stupid imo.

gonadic io fucked around with this message at 20:42 on Oct 16, 2015

Volte
Oct 4, 2004

woosh woosh
They ought to dispose of the standard library and do it Agda-style, where the standard library is just a library that you have to include, and you can use whichever one you want. I was already losing interest in Haskell and now the push to make it even more academic is only strengthening that. Luckily Scala came along just in time to pick up where Haskell left off, as far as I'm concerned.

gonadic io
Feb 16, 2011

>>=
scala has a lot more warts, and needs to have it's standard library reduced by 50% imo. it kinda suffers from the problem of lots of hybrid langs - f#, and even python in that there are lots of ways to do anything and most of them have annoying non-obvious flaws. THREE different ways for functions to take arguments, 2+ different ways to define functions, all of which can be combined freely. don't even loving mention implicits. it's a nightmare without strict code reviews.

to be fair, there is a large counterpush to the changes in haskell, lots of people saying that the language committee is overreaching etc. hence why i said a python 2/3 split, rather than just making the changes.

gonadic io fucked around with this message at 20:53 on Oct 16, 2015

gonadic io
Feb 16, 2011

>>=
i mean i'm kinda sympathetic to the people wanting to modernise haskell's prelude since it does often annoy me, and ditto for strings being [char] rather than text. but still, changing the current prelude isn't the way to go about it.

gonadic io
Feb 16, 2011

>>=
also some of the changes ARE backwards compatible in terms of code (using traversable instead of hard-coding lists for example) but make type-sigs (in error messages, documentation, and ghci) far more opaque.

pro: it doesn't take long to get used to it, the language should be about its most common users
con: shut up, first impressions are important, the language shouldn't put barriers in the way of newcomers

Adbot
ADBOT LOVES YOU

Malcolm XML
Aug 8, 2009

I always knew it would end like this.
NoImplicitPrelude now mandatory

Prelude = ez for beginners
Prelude2 = the one people actually use

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply