Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 03:05
    maxfierke synchronize #11302
  • Oct 17 23:02
    maxfierke synchronize #11302
  • Oct 17 20:48
    Blacksmoke16 labeled #11333
  • Oct 17 20:48
    Blacksmoke16 opened #11333
  • Oct 17 19:21
    Blacksmoke16 edited #11332
  • Oct 17 19:17
    Blacksmoke16 opened #11332
  • Oct 17 19:17
    Blacksmoke16 labeled #11332
  • Oct 17 17:19
    sardaukar closed #11330
  • Oct 17 14:44
    Blacksmoke16 edited #11331
  • Oct 17 14:31
    Blacksmoke16 labeled #11331
  • Oct 17 14:31
    Blacksmoke16 opened #11331
  • Oct 17 13:22
    HertzDevil labeled #11330
  • Oct 17 13:14
    sardaukar labeled #11330
  • Oct 17 13:14
    sardaukar opened #11330
  • Oct 17 04:40
    maxfierke edited #11302
  • Oct 17 04:33
    maxfierke synchronize #11302
  • Oct 17 02:37
    maxfierke edited #11329
  • Oct 17 02:27
    maxfierke labeled #11329
  • Oct 17 02:27
    maxfierke opened #11329
  • Oct 17 02:25
    Blacksmoke16 edited #11328
mfiano
@mjfiano:matrix.org
[m]
I need some help with blocks. Not sure if what I want is possible.

I'm trying not to get into macros at this point, so ignoring them. I have a bunch of methods that all repeat a lot of code. Here's 2 of them:

    def round
      v = dup
      v.each_with_index { |elt, i| v[i] = elt.round }
      v
    end

    def abs
      v = dup
      v.each_with_index { |elt, i| v[i] = elt.abs }
      v
    end

So I was thinking of making a method:

    private def element_wise(&block)
      v = dup
      v.each_with_index { |elt, i| v[i] = ... }
      v
    end

That does all the logic, and I would like to pass in the ellipsized part to be executed if possible like:

    def round
      element_wise { round }
   end

or something or other.

mfiano
@mjfiano:matrix.org
[m]
Is this even possible or should I abort now? :)
George Dietrich
@Blacksmoke16
v = dup
v.each_with_index { |elt, i| v[i] = yield elt }
v
actually what you want is prob v[i] = with elt yield
at which point you could prob just do like
element_wise &.round
but this is probably a good use case for macros
as the methods are all the same
mfiano
@mjfiano:matrix.org
[m]
with elt yield worked, but not with &.round...had to be { round }
George Dietrich
@Blacksmoke16
the former should work if you just do yield elt
iirc with .. yield is kinda buggy in some cases
so :shrug:
mfiano
@mjfiano:matrix.org
[m]
Pretty nifty, it works
This will do until I macroize things, thanks
George Dietrich
@Blacksmoke16
:thumbsup:
mfiano
@mjfiano:matrix.org
[m]
I'm not quite sure how I'd call element_wise for this one though, as it takes a second argument:
    def copysign(other : self)
      x = Math.copysign @x, other.x
      y = Math.copysign @y, other.y
      V2.new x, y
    end
George Dietrich
@Blacksmoke16
prob just keep it as is?
mfiano
@mjfiano:matrix.org
[m]
There's a bunch like that. They all have the same pattern, just additional args
George Dietrich
@Blacksmoke16
id say just go with a macro imo
even if you have a helper private method its still just boilerplate
mfiano
@mjfiano:matrix.org
[m]
I'm feeling a little intimidated by Crystal macros still
Spent last night trying to figure out the basics from reading the docs...couldn't apply it to my own code
George Dietrich
@Blacksmoke16
{% for m in ["round", "abs"] %}
    def {{m.id}}
      v = dup
      v.each_with_index { |elt, i| v[i] = elt.{{m.id}} }
      v
    end
{% end %}
assumes the method name is the same as the method called on the element, but could easily work around that if thats not what you want
mfiano
@mjfiano:matrix.org
[m]
In my case, I'd only want to generate the method body, not the whole method, supplying the name of the method called on the element
and therefor without a hard-coded list of strings too
George Dietrich
@Blacksmoke16
why would it matter?
mfiano
@mjfiano:matrix.org
[m]
@Blacksmoke16: I took your advice 😀
George Dietrich
@Blacksmoke16
:thumbsup:
mfiano
@mjfiano:matrix.org
[m]
George Dietrich
@Blacksmoke16
hmm
i have an idea
mfiano
@mjfiano:matrix.org
[m]
This is intended to be included on all 3 of my vector types. I may split it up into 2 mixins, for the methods that don't make sense for matrices
George Dietrich
@Blacksmoke16
private macro element_wise(name, &)
  def {{name.id}}
    out = dup
    each_with_index { |elt, idx| out[idx] = {{yield}} }
    out
  end
end

element_wise fract do
  elt - elt.floor
end
I think that should work
or even element_wise frac { elt - elt.floor }
mfiano
@mjfiano:matrix.org
[m]
Idea is to try to get rid of all references to @x, @y, etc so it's DRY for the related types
Oh, lemme read
George Dietrich
@Blacksmoke16
also fwiw out is a keyword so prob wouldn't be a bad idea to pick something else
technically works, but going to mess up highlighting
mfiano
@mjfiano:matrix.org
[m]
I mean, that doesn't save any code by expanding into a toplevel definition, and imho isn't as easy to scan the file
George Dietrich
@Blacksmoke16
:thinking: how do you figure that doesn't save any code?
mfiano
@mjfiano:matrix.org
[m]
re: out: ok
9-11 are 3 lines. so is 24-26 in mine?
George Dietrich
@Blacksmoke16
  def sign
    element_wise elt.sign.to_f
  end

  def copysign(other : self)
    element_wise Math.copysign elt, other[idx]
  end

  def fract
    element_wise elt - elt.floor
  end
Gets turned into:
element_wise sign { elt.sign.to_f }
element_wise copysign { Math.copysign elt, other[idx] }
element_wise fract { elt - elt.floor }
mfiano
@mjfiano:matrix.org
[m]
I could just as well do that with mine since they're short, albeit a bit differently
The benefit is I instantly know they are defs, and syntax highlighting gives my brain less to process when quickly scanning a source file
Correct me if I'm wrong :)
George Dietrich
@Blacksmoke16
fair enough