-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow to initialise Named Tuples with same notation as Objects #321
Comments
Could you share the use case where you prefer to use tuples instead of objects and therefore use this initialization syntax? Currently it's also possible to initialize tuple like this: In my experience tuples are clunkier to operate when used extensively:
I use objects and when I need a short notation for e.g. |
Like this one: type Cash* = tuple[amount: float, currency: string]
let cash = Cash(amount: 1.0, currency: "USD") I like ability to use shortcut initialisation like P.S. Some more cases Price* = tuple[price: float, currency: string, time: Time]
type Point* = (Time, float)
# With some conversion magic
let prices: seq[Point] = @[
((1990, 1, 1), 1.0),
((2000, 1, 1), 1.0), ((2000, 1, 2), 3.0),
((2000, 2, 1), 1.0)
]
But why? Why add more and more ways to do the same thing? Wouldn't it be better and simpler to write |
I can't answer "why" exactly but I have several thoughts about your use case. I would use objects instead of tuples every time. Tuples have 2 benefits:
1st one is remedied by the use of converters, you can achieve any level of convenience in code. 2nd one is debatable at best especially considering that you need to do financial stuff. So to me it looks like "ugliness on purpose" that you shouldn't really use tuples for these use cases. But the general idea about consistency with object initialization looks good. I don't see a use case where I explicitly need to know that this is object, not tuple construction. |
The real problem with using tuples instead of objects is that they expose field-order-based iteration which some knuckehead is going to end up depending upon. As soon as you want to upgrade to an object, you break that code. I really don't understand why people want to typedef tuples; to me it's code smell every time. |
Isn't the real answer here to instead to create field iteration differences rather than initialization differences? The the current approach is creating a referred pain at some initialization site as opposed to the site of any traversal (or parameter) that may be traversal order dependent. |
type Cash* = object
amount: float
currency: string
proc usd(amount: float): Cash = Cash(amount: amount, currency: "USD")
let cash = 1.usd This is a style I've adopted into my code, it works pretty well, and I'd argue it looks much better than your import std/strutils
template currency(name: untyped) =
const currencyName = astToStr(name).toUpperAscii
proc `name`(amount: float): Cash {.inject.} =
Cash(amount: amount, currency: currencyName)
currency usd
currency eur |
I agree that I'd rather have object/tuple construction that wraps identdefs and I'd rather have consistent syntax, but to me, it's more important to improve the documentation on tuples to prevent people from thinking that they are somehow buying themselves anything more than future grief. Have fun adding a field to that tuple; you still have to change all your initializations... |
There are different ways tuples could be used or even avoided. But why have different syntax for it? Wouldn't it be better to keep syntax same and uniform? P.S.
I think it's ok and convenient to use positional unpacking for tuples of size of 2-3, the problem you mentioned usually arises when the tuple size is >3. And, maybe some day Nim would support name based unpacking for tuples and objects. So people would use key unpacking |
In my opinion a better syntax that would actually fit the language would be |
Unpacking is yet another problem, but no less annoying to deal with regardless of how large your tuples are. It has the feature that you must hope that the names and types of the fields you're unpacking will not change, otherwise, you can't trust that your code will remain correct. Yet another reason not to use tuples except in very limited circumstances. This is a partial solution: https://github.com/disruptek/foreach It should probably be modified to simply use the identdef syntax as @liquidev proposes; maybe it should desugar assignments as well. |
Rejected. Nobody is working on it and it's hardly important. Just start with |
It would be convenient to support both tuple and object initialisation for Named Tuples.
Frequently code that uses tuple doesn't need to know how it's implemented - if it's an object or tuple. Say I decided to change Person from object to tuple - and now I have to update tons of old code
Person(name: name)
.It just feels right and uniform.
The text was updated successfully, but these errors were encountered: