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
Kahli Burke
@kahliburke
Sure, sorry I didn't figure it out myself...
Kahli Burke
@kahliburke
If you have any time to talk about stuff related to this library, my difficulty now is in trying to optimize the size of the macro generated code. In particular the differing implementation of Jvm vs Js as imported via the @enableMembersIf macro led me to the discovery that in deeply nested calls, ScalaJS does not optimize away certain conversion between Seq and js.Array (https://github.com/ThoughtWorksInc/Binding.scala/blob/1300e7bf0dbff01ccf100ad2fa4b7cc414cdd116/Binding/src/main/scala/com/thoughtworks/binding/Binding.scala#L146) which results in larger blocks of code than is necessary. I've inquired about it on the scala-js channel. Also, just trying to figure out how to reduce the resulting code size to make the fastOpt process run "fast". Large DOM views result in a lot of nested calls, and I'm curious whether some of the domBindingSeq calls from macros could be improved to prevent sibling nodes from producing nested Bindings.
Yang, Bo
@Atry
How about removing the @inline annoation from toConstantsData?
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.