Code Monkey home page Code Monkey logo

Comments (27)

joevandyk avatar joevandyk commented on June 8, 2024 2

i'll take a stab at this tonight

from dry-types.

flash-gordon avatar flash-gordon commented on June 8, 2024 2

Want to mention that to_* and Kernel methods have different semantics, Integer() will raise a TypeError if coercion is not possible and to_i will throw a NoMethodError.

from dry-types.

solnic avatar solnic commented on June 8, 2024 1

One more thing:

i found workaround but it looks very ugly

What's ugly about it? It's not a workaround, it's the way of using this library :)

from dry-types.

solnic avatar solnic commented on June 8, 2024 1

@georgemillo that's why I suggested that Coercible should be renamed to Kernel or KernelCoercion to make it more obvious.

It seems to me that the important thing about these Types is that they coerce, not that they coerce using a particular method

Actually, one of the biggest reasons why dry-types was created was to split coercion into different categories so that we can use dedicated coercion logic depending on the use case. That's why there's Coercible (but as I mentioned I don't like that name), Form and JSON (and we'll add Params for http params, and Form/JSON will reuse a lot from it). This way it's simpler and faster, and your code that uses dry-types is more intentional.

from dry-types.

waiting-for-dev avatar waiting-for-dev commented on June 8, 2024 1

In fact, the thing is that Ruby semantics are not very consistent... For example, Kernel#String() will try to call first #to_str and then #to_s . Calling #to_s is by no means an acceptable way to coerce a type to a string (for example, Object#to_s).

My thought know is that the best thing to do would be to keep ruby semantics as an implementation detail (or expose them but not as the main API hierarchy) and to propose a consistent and rational type coercion system. That means adding Coercible::Symbol, keeping Coercible::Bool, changing Coercible::String so that it just tries to call #to_str or #to_s in a whitelist of classes (like Integer), and maybe something more.

Let me know what you decide and whether I can help in anything.

from dry-types.

solnic avatar solnic commented on June 8, 2024

This was already done last year, by me, oh well.

from dry-types.

morr avatar morr commented on June 8, 2024

@solnic Symbol is put in NON_COERCIBLE in this commit 761e759
Can you make it coercible again?

from dry-types.

morr avatar morr commented on June 8, 2024

I found workaround but it looks really ugly

Types::Strict::Symbol
  .constructor(-> (val) { val.to_sym })
  .enum(:a, :b, :c)

from dry-types.

solnic avatar solnic commented on June 8, 2024

@morr Coercible uses coercion methods from Kernel and there's no Kernel.Symbol so we won't have coercible symbol. We could add coercible symbol to other types, like form or json.

from dry-types.

morr avatar morr commented on June 8, 2024

Because of the way of using it for strings :)

Types::Coercible::String('a', 'b', 'c')

vs

Types::Strict::Symbol
  .constructor(-> (val) { val.to_sym })
  .enum(:a, :b, :c)

from dry-types.

solnic avatar solnic commented on June 8, 2024

@morr you can just do this:

Types::Strict::Symbol.constructor(&:to_sym).enum(:a, :b, :c)

We can also think about adding a new type category for to_* coercions, so we have Coerible which uses Kernel coercion functions, and we'd have another one that uses to_s to_sym to_i and so on.

from dry-types.

george-carlin avatar george-carlin commented on June 8, 2024

Just wondering why it's so important that the Coercible types are completely internally consistent in how they coerce a value? It seems to me that the important thing about these Types is that they coerce, not that they coerce using a particular method, and I don't see why users should be forced to think about subtle idiosyncrasies of Ruby itself (such as that there's a String() and a Integer() Kernel method but no Symbol()) just to coerce a type. (It's also worth nothing that when it comes to strings for example, String() is identical to to_s anyway except in some very rare cases that are barely worth considering, so it's not like a second set of types that uses to_s instead of String() would really make a difference anyway.)

Similarly, Ruby has no class called Boolean, only TrueClass and FalseClass. But we don't let this idiosyncrasy of Ruby stop us from adding a type called Bool, since it's a common use case that users will expect to be covered. Types::Strict::Bool is fundamentally different internally from the other types in the Strict namespace, but it doesn't matter because users don't care about the internals, they just care that their type is a bool. Why not apply a similar logic to users who care about coercing input to a symbol?

from dry-types.

waiting-for-dev avatar waiting-for-dev commented on June 8, 2024

We can also think about adding a new type category for to_* coercions, so we have Coercrible which uses Kernel coercion functions, and we'd have another one that uses to_s to_sym to_i and so on.

@solnic @flash-gordon it seems it wasn't implemented. Could I take this one? If so, should we rename Coercible to Kernel? And which name do you like for #to_* coercions?

from dry-types.

solnic avatar solnic commented on June 8, 2024

@waiting-for-dev first we need to decide IF we want to add this. I'm on the fence now, you'd rarely need it.

from dry-types.

waiting-for-dev avatar waiting-for-dev commented on June 8, 2024

@solnic I think you are right. There is nothing that right now you can't do and that the new namespace would allow you. It seems it would make the library more comprehensive, but, after a second thought, I would leave as it is unless we find better reasons.

The only reason I miss it from time to time is when I have to write:

Types::Strict::Symbol.constructor(&:to_sym)

Sure I'm too fussy, but I don't like seeing Strict and :to_sym in the same line (it confuses me at first sight because they sound incompatible) and I would like just to be able to do Types::Coercible::Symbol, because it makes sense in my head, although I understand that it is a good thing to keep the semantics of the language. At the end, it is ruby's fault because there is no Kernel#Symbol() method :) Maybe we could add a type constructor helper for, at least, make it shorter? Something like Types.ToSymbol()

from dry-types.

solnic avatar solnic commented on June 8, 2024

We could consider adding Params::Symbol and JSON::Symbol

from dry-types.

waiting-for-dev avatar waiting-for-dev commented on June 8, 2024

Hmm, but sometimes you need it outside the scope of params and json coercions. I'm also using dry-types for non web development.

from dry-types.

solnic avatar solnic commented on June 8, 2024

Types::Strict::Bool is fundamentally different internally from the other types in the Strict namespace, but it doesn't matter because users don't care about the internals, they just care that their type is a bool. Why not apply a similar logic to users who care about coercing input to a symbol?

So, I'm actually having second thoughts about this. It is true that we diverged from Ruby's semantics with Bool. I can also see how the lack of Coercible::Symbol may surprise people.

I think I'm OK with adding it, after all. Just needed 3 years to reconsider 😆 I'll talk to other core devs about this.

from dry-types.

flash-gordon avatar flash-gordon commented on June 8, 2024

a consistent and rational type coercion system

I don't think this is a feasible thing :)

from dry-types.

waiting-for-dev avatar waiting-for-dev commented on June 8, 2024

a consistent and rational type coercion system

I don't think this is a feasible thing :)

I think you are right :D But maybe we can reach until a certain degree taking a very conservative approach.

I think I'm OK with adding it, after all. Just needed 3 years to reconsider laughing I'll talk to other core devs about this.

@solnic did you and dry-rb team conclude something definitive?

from dry-types.

solnic avatar solnic commented on June 8, 2024

@waiting-for-dev no, the focus was on other things

from dry-types.

waiting-for-dev avatar waiting-for-dev commented on June 8, 2024

Ok, sorry for the push, I just wanted to know in order to collaborate with the implementation. I'll wait, I understand this is no high priority right now.

from dry-types.

solnic avatar solnic commented on June 8, 2024

@timriley @flash-gordon are you OK with adding Coercible::Symbol and moving away from the idea that Coercible are only for coercions handled by Kernel?

from dry-types.

flash-gordon avatar flash-gordon commented on June 8, 2024

I don't mind. I don't think adding a whole bunch of coercible types that use to_* for coercions makes sense. It looks more reasonable to add what's missing to Coercible instead.

from dry-types.

timriley avatar timriley commented on June 8, 2024

@solnic @flash-gordon I'm happy for us to add Coercible::Symbol using #to_sym under the hood.

I do think we should aim to keep the Coercible family of types relatively small, but given the importance and wide use of symbols within typical Ruby programs, I think it needs to be in it.

from dry-types.

solnic avatar solnic commented on June 8, 2024

OK so we have an agreement 🤝 😄

from dry-types.

solnic avatar solnic commented on June 8, 2024

I re-opened this issue and update the description

from dry-types.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.