by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Aug 07 06:53
    scala-steward opened #287
  • Jul 27 16:34
    scala-steward opened #286
  • Jul 20 19:58
    scala-steward opened #285
  • Jul 11 00:24
    scala-steward opened #284
  • Jun 30 21:04
    scala-steward opened #281
  • Jun 29 15:04
    scala-steward opened #280
  • Jun 28 01:13
    scala-steward opened #279
  • Jun 19 15:53
    scala-steward opened #278
  • Jun 19 04:48
    scala-steward opened #277
  • Jun 17 03:38
    scala-steward opened #276
  • Jun 15 21:37
    scala-steward opened #275
  • May 29 06:09
    Atry closed #262
  • May 29 06:09
    Atry commented #262
  • May 29 06:01

    Atry on v12.0.0

    (compare)

  • May 29 05:37

    Atry on master

    Update README.md (compare)

  • May 29 05:27

    Atry on master

    Update README.md (compare)

  • May 28 23:52

    Atry on master

    Update scalatest to 3.1.2 Merge pull request #272 from sc… (compare)

  • May 28 23:52
    Atry closed #272
  • May 28 23:52
    Atry closed #271
  • May 28 23:52
    Atry closed #270
Yang, Bo
@Atry
Those nested calls are actually IIFEs. See scala-js/scala-js#2675
Kahli Burke
@kahliburke
Something to try... I remember reading this discussion between the two of you earlier, thanks for making that connection. So is it possible to avoid them?
If I have many sibling nodes like
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
    <div>b</div>
That can result in lots of nesting too
Yang, Bo
@Atry
Because they are monadic expressions
Kahli Burke
@kahliburke
Yeah, I was curious if it was possible to capture that in a single monad
Yang, Bo
@Atry
It performs something like CPS-transformation
Kahli Burke
@kahliburke
Yes, I am passingly familiar with it although I'm certain you have a more detailed understanding given your work. So, trying to ask an expert :)
Seems like OutputMode.ECMAScript6 might offer a solution in the long term but not possible in current browsers, correct?
Yang, Bo
@Atry
Those IIFEs are not necessary for fullOpt even in current browsers because:
  • The code generated by Scala.js will be passed to Closure compiler
  • Closure compiler support ECMAScript2015 input
  • Scala.js can produce ECMAScript2015 output
We need some changes in Scala.js:
  • Don't generate IIFEs if the output mode is ECMAScript2015
  • Switch to ECMAScript2015 output mode in fullOpt, to generate the code for Closure compiler
Kahli Burke
@kahliburke
Thanks for the clarification. Explains why things are much improved in the fullOpt version, this is mainly a development concern for me, the fastOpt process takes a long time and results in 20MB output.
As I write more UI, this scales up quickly
If you have an idea of clever workarounds within Binding.scala, let me know as I would invest some time into it.
Yang, Bo
@Atry
You may try to add a condition for IIFE generation that detects if the output mode is ECMAScript2015. I guess it will be a small change in https://github.com/scala-js/scala-js.
Kahli Burke
@kahliburke
Oh on reading your note again I see I misunderstood you... the IIFEs are currently present in fullOpt but could be dealt with via Closure compiler if Scala.js would produce the ECMAScript2015/ES6 output
That sounds like a good idea, as in development it's not a problem to use a modern browser that supports ECMAScript2015.
Yang, Bo
@Atry
It's irrelevent. Clousure compiler can convert ES2015 to ES5
Kahli Burke
@kahliburke
Ok, but for development workflow we would use fastOpt which does not pass through Closure, correct?
Yang, Bo
@Atry
I guess @sjrd also wants to reduce number of IIFE generation even for ES5.
Kahli Burke
@kahliburke
That would be great too, but for development I could simply enforce ES6 output and make sure devs use a modern browser? So I'd get the benefit of no IIFEs in dev mode, but that code would then work across a wider browser suite once pushed through fullOptJs?
Yang, Bo
@Atry
Yes. Totally disabling IIFE for ES6 is a easier change than delicately reducing IIFEs.
Kahli Burke
@kahliburke
Anyway, I think you've inspired some good ideas on where to focus effort. Thanks for taking the time to discuss it, time to start looking at the scala-js codebase to see if that's at all penetrable by mere mortals.
Yang, Bo
@Atry
Thank you, too!
Kahli Burke
@kahliburke
Glad we met in the same time slot, talk again later :)
Yang, Bo
@Atry
:smile:
Basim Khajwal
@basimkhajwal

Hi, could someone point out what the cause of this error is in the following import com.thoughtworks.binding.Binding.{ Var, Vars }
import com.thoughtworks.binding.dom
import org.scalajs.dom.document

case class Model(name: String, contents: Vars[Double])

@dom
def render = {

val models = Vars(
Model("A Model", VarsDouble)
)

<div>
{
for (model <- models) yield {
<h3>{model.name}</h3>
<ul>
{
for (i <- model.contents) yield {
<li>{i.toString}</li>
}
}
</ul>
}
}
</div>
}

dom.render(document.body, render)

Sorry, forgot to format

The following code is what I'm trying to achieve in my own project (with a more complicated interface but the same error is what I am finding difficult to overcome).

import com.thoughtworks.binding.Binding.{ Var, Vars }
import com.thoughtworks.binding.dom
import org.scalajs.dom.document

case class Model(name: String, contents: Vars[Double])

@dom
def render = {

  val models = Vars(
    Model("A Model", Vars[Double](1,2,3))
  )

  <div>
    {
      for (model <- models) yield {
        <h3>{model.name}</h3>
        <ul>
        {
          for (i <- model.contents) yield {
            <li>{i.toString}</li>
          }
        }
        </ul>
      }
    }
  </div>
}

dom.render(document.body, render)

Running this (https://scalafiddle.io/sf/9eib3hm/0) gives the following error:

ScalaFiddle.scala:16: error: overloaded method value domBindingSeq with alternatives:
  ( text: String )binding.this.Binding.Constants[raw.this.Text] 
    ( node: raw.this.Node )binding.this.Binding.Constants[raw.this.Node] 
      ( seq: Seq[raw.this.Node] )binding.this.Binding.Constants[raw.this.Node] 
        ( bindingSeq: .this.com.thoughtworks.binding.Binding.BindingSeq[raw.this.Node] ).this.com.thoughtworks.binding.Binding.BindingSeq[raw.this.Node]
         cannot be applied to (.this.com.thoughtworks.binding.Binding.BindingSeq[.this.com.thoughtworks.binding.Binding.BindingSeq[raw.this.Node]])
    for (model <- models) yield {
                           ^
    }

Any help would be appreciated

Kahli Burke
@kahliburke
But in general the issue with using for/yield is that it turns into a map operation, when you really want a flatMap for what you're doing. So an alternative way would be to do:
models flatMap { model =>
        <h3>
          {model.name}
        </h3>
        <ul>
          {for (i <- model.contents) yield {
          <li>
            {i.toString}
          </li>
        }}
        </ul>
      }
This is only an issue when you're returning a sequence of xml elements from each element in a Vars or some other collection.
Basim Khajwal
@basimkhajwal
@kahliburke Thanks a lot, I didn't realise the for comprehension was actually using a map operation. In my mind I thought that if it worked for a regular Binding it would also work for a BindingSeq.
Kahli Burke
@kahliburke
@basimkhajwal In scala a for comprehension is syntactic sugar for chaining flatMap, map -> https://docs.scala-lang.org/tutorials/FAQ/yield.html#translating-for-comprehensions
Kahli Burke
@kahliburke
@Atry I'm wondering if you can clarify use of Var.value given the comment * @note This method must not be invoked inside a @dom method body.?
Is that purely about the @dom macro or does that extend to setting Var.value inside a Binding{ .. } block?
Yang, Bo
@Atry
A @dom function is just a HTML template, which should be pure without any side effects, so doBinding blocks.
Both .value and .value_= are side effects.
Kahli Burke
@kahliburke
Yes, that's clear about.value causing side effects. But doing Binding { someVar.value = someBInding.bind}.watch would be ok?
Yang, Bo
@Atry
It's very dangerous. Don't do that.
Kahli Burke
@kahliburke
Haha
Ok, I'm trying to figure out how to accomplish setting of a Var, say related to a user's choice in UI from some other Binding value that can sometimes change
Yang, Bo
@Atry
That may create circular dependencies, and may cause some reentry bugs in Binding.scala's internal implementation.
Kahli Burke
@kahliburke
Yeah that's what I was concerned about too.. One option seemed to put Var.value = inside a Future block
Yang, Bo
@Atry

Ok, I'm trying to figure out how to accomplish setting of a Var, say related to a user's choice in UI from some other Binding value that can sometimes change

You can try to not use Var for that case. Use Binding block instead.

Lorenzo Gabriele
@lolgab
Are there plans to support scala native?
Yang, Bo
@Atry

Yeah that's what I was concerned about too.. One option seemed to put Var.value = inside a Future block

There is a FutureBinding for remote data. You can use it instead of Vars.

@lolgab It would be not very hard to support scala-native. PR is welcomed.