Code Monkey home page Code Monkey logo

Comments (6)

a-h avatar a-h commented on August 25, 2024 2

I've seen some people doing things like defining a really short function name. Sort of mirrors what quicktemplate does - IIRC, it has a {%d var %} placeholder.

func d(i int) string {
  return strconv.Itoa(i)
}

templ component(i int) {
  { d(i) }
}

I'm open to the community consensus on this too. If everyone thinks it's OK to use default formatting for basic types, I'd be open to changing the behaviour.

from templ.

kynrai avatar kynrai commented on August 25, 2024 1

Yep I have done the same for things like URLs for htmx and various other things. Ill continue to do that

from templ.

joerdav avatar joerdav commented on August 25, 2024

I don't think this a silly idea, it isn't niche either I've seen people mention this before.

My main concern here is to ensure we keep it so that it type safe (don't accept any type), and predictable (don't try and handle any complex cases such as structs or times).

One solution would be to use generics in the generated code:

Currently the go expressions get passed to func JoinStringErrs(s string, errs ...error) (string, error).

Maybe this could be expanded into a function such as:

func JoinExpressionErrors[T constraints.Ordered](s T, errs ...error) (string, error)

We don't have to use Ordered, but some sort of constraint that defines which types we want to allow would be best. Maybe just [T ~string | constraints.Integer] for now?

from templ.

a-h avatar a-h commented on August 25, 2024

I can see why it seems a bit obtuse to force string formatting, but I'm fairly sure it's the right thing to do.

The initial commercial use of templ was for creating insurance documents. We used int64 as the type for money, which is exactly what payments company Stripe uses: https://docs.stripe.com/api/charges/object#charge_object-amount

So, in our case, 100 means £1 GBP. In the USA the number 100 would mean $1.

What I really didn't want, was that we'd show a customer that they would get a refund of 1000, and for customers to think they were going to get £1000, when actually, they were going to get £10.

As you can imagine, the default way to print out a number is without thousand separators (and even those vary by region - e.g. Germany uses 1.000 whereas in the UK, it would be 1,000), so if we let numbers get displayed, then we'd have to default to something.

Similarly, other types that are converted implicitly could result in unexpected errors. For example, date formatting. With fmt.Println(time.Now()) you get 2009-11-10 23:00:00 +0000 UTC m=+0.000000001 as output. With daylight saving in the UK, the date (or even year) might not print what you'd expect.

If I want to render an object, I might choose the JSON representation, but then I'd potentially end up rendering private data to the customer, e.g. fraud risk flags, and I'm not sure I'd want to trust the Stringer interface to display stuff to my customer.

I definitely don't want to display the word nil to a customer too!

So the idea was that defaulting to a string forces the need to be explicit.

The general philosophy of templ is:

  • Secure by default
  • Follow the principle of least surprise - things should behave predictably, with low effort to learn
  • Prefer compile time errors, and development time hassle over runtime errors - end users suffer runtime ones, and may never tell the developer about the problem
  • Sustainable - be able to sustain this project over the long term without a lot of resources
  • No config file, and definitely no YAML - partly about sustainability because it's hard to maintain multiple behaviour paths
  • Don't break people's code - unless you really have to for the long term success of the project

I think forcing strings is not surprising (at runtime), but then, React allows rendering of numbers (including NaN), and strings, but not objects, so maybe it is surprising, and templ is being annoying!

from templ.

kynrai avatar kynrai commented on August 25, 2024

I can see your reasoning and it makes a lot of sense, my main issue was mainly a DX one, I can see when people send ints in particular and want to render it, they likely mean that exact int, currency formatting makes sense when you describe it as an int for the lowest denomination which I agree is correct.

I guess thats down to the user and testing, when they print out 1000 and mean £10.00 not £1000, forcing them to format in the template or pass in the final string, both are explicit enough.

Again just to be clear, I find myself covnering from int to string a lot, which was my primary motivation, this does also open flood gates to the remaning go types.

fmt.Sprint would invoke stringer which might not be the desired effect in some cases for example something like,

type Cash int

func (Cash) String() string { return "One"}

fmt.Sprinf(Cash(1))

so i take your point about not relying on stringer. this leaves strconv.Itoa which is acceptable but felt like if if it was only even an int then it could be implicit but that violates the lease suprise rule or maybe its a suprise to people it does not render the int, i do not know.

Maybe need more community input on this instead of just my own selfish request hehe

from templ.

joerdav avatar joerdav commented on August 25, 2024

Sounds like we are happy with the existing behavior, feel free to re-open with any more arguments for expanding this feature.

from templ.

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.