Asked  6 Months ago    Answers:  5   Viewed   26 times

What exactly is type coercion in Javascript?

For example, on the use of == instead of ===?

 Answers

24

Type coercion means that when the operands of an operator are different types, one of them will be converted to an "equivalent" value of the other operand's type. For instance, if you do:

boolean == integer

the boolean operand will be converted to an integer: false becomes 0, true becomes 1. Then the two values are compared.

However, if you use the non-converting comparison operator ===, no such conversion occurs. When the operands are of different types, this operator returns false, and only compares the values when they're of the same type.

You can find a good explanation of JavaScript's coercion rules in You Don't Know JS and more reference-oriented documentation in MDN.

Tuesday, June 1, 2021
 
Corne
answered 6 Months ago
76

First off, * is not a wildcard! It's also typically pronounced "star."

Bleeding edge note: There is as of Feb. 2015 a proposal to simplify GHC's subkind system (in 7.12 or later). That page contains a good discussion of the GHC 7.8/7.10 story. Looking forward, GHC may drop the distinction between types and kinds, with * :: *. See Weirich, Hsu, and Eisenberg, System FC with Explicit Kind Equality.

The Standard: A description of type expressions.

The Haskell 98 report defines * in this context as:

The symbol * represents the kind of all nullary type constructors.

In this context, "nullary" simply means that the constructor takes no parameters. Either is binary; it can be applied to two parameters: Either a b. Maybe is unary; it can be applied to one parameter: Maybe a. Int is nullary; it can be applied to no parameters.

This definition is a little bit incomplete on its own. An expression containing a fully-applied unary, binary, etc. type constructor also has kind *, e.g. Maybe Int :: *.

In GHC: Something that contains values?

If we poke around the GHC documentation, we get something closer to the "can contain a runtime value" definition. The GHC Commentary page "Kinds" states that "'*' is the kind of boxed values. Things like Int and Maybe Float have kind *." The GHC user's guide for version 7.4.1, on the other hand, stated that * is the kind of "lifted types". (That passage wasn't retained when the section was revised for PolyKinds.)

Boxed values and lifted types are a bit different. According to the GHC Commentary page "TypeType",

A type is unboxed iff its representation is other than a pointer. Unboxed types are also unlifted.

A type is lifted iff it has bottom as an element. Closures always have lifted types: i.e. any let-bound identifier in Core must have a lifted type. Operationally, a lifted object is one that can be entered. Only lifted types may be unified with a type variable.

So ByteArray#, the type of raw blocks of memory, is boxed because it is represented as a pointer, but unlifted because bottom is not an element.

> undefined :: ByteArray#
Error: Kind incompatibility when matching types:
   a0 :: *
   ByteArray# :: #

Therefore it appears that the old User's Guide definition is more accurate than the GHC Commentary one: * is the kind of lifted types. (And, conversely, # is the kind of unlifted types.)

Note that if types of kind * are always lifted, for any type t :: * you can construct a "value" of sorts with undefined :: t or some other mechanism to create bottom. Therefore even "logically uninhabited" types like Void can have a value, i.e. bottom.

So it seems that, yes, * represents the kind of types that can contain runtime values, if undefined is your idea of a runtime value. (Which isn't a totally crazy idea, I don't think.)

GHC Extensions?

There are several extensions which liven up the kind system a bit. Some of these are mundane: KindSignatures lets us write kind annotations, like type annotations.

ConstraintKinds adds the kind Constraint, which is, roughly, the kind of the left-hand side of =>.

DataKinds lets us introduce new kinds besides * and #, just as we can introduce new types with data, newtype, and type.

With DataKinds every data declaration (terms and conditions may apply) generates a promoted kind declaration. So

 data Bool = True | False

introduces the usual value constructor and type name; additionally, it produces a new kind, Bool, and two types: True :: Bool and False :: Bool.

PolyKinds introduces kind variables. This just a way to say "for any kind k" just like we say "for any type t" at the type level. As regards our friend * and whether it still means "types with values", I suppose you could say a type t :: k where k is a kind variable could contain values, if k ~ * or k ~ #.

Sunday, July 11, 2021
 
Grzegorz
answered 5 Months ago
26

The argument is a DOMHighResTimeStamp, just like what Performance.now is supposed to return, even if it isn't the one returned by this method.


So first let explain the difference in precision you are seeing: Recently a major security issue has been discovered in the majority of CPUs, known under the names of Meltdown and Spectre.
These attacks can be perpetrated from a web browser, but requires the DOMHighResTimeStamp returned by Performance.now. A quick-fix / "mitigation", Firefox found, was to lower the resolution of this DOMHighResTimeStamp. (see more).

Since requestAnimationFrame callbacks are scheduled to fire the next frame (i.e ~16ms after previous call) the DOMHighResTimeStamp passed from this method doesn't require this mitigation, hence you still have the full precision in this DOMHighResTimeStamp.


Now to answer the title's question, the DOMHighResTimeStamp passed in requestAnimationFrame's callbacks represents the calling time of the stack of all callbacks for this frame.
Indeed, requestAnimationFrame only store the callback parameter in a stack, and this stack is then called when the frame occurs (just before the next painting operation).
This means that all the callbacks for the same frame will share the same exact DOMHighResTimeStamp, without any regard to how long the previous callback took.

function long(time){
  var now = performance.now();
  console.log('long');
  console.log({
    'rAF time': time,
    'Performance time': now,
    'diff': (now - time) + 'ms'
  });
  console.log('________________________');
  // wait 50ms
  while(performance.now() - time < 50) {
  }
}
function short(time) {
  var now = performance.now();
  console.log('short');
  console.log({
    'rAF time': time,
    'Performance time': now,
    'diff': (now - time) + 'ms'
  });
}
// our two functions will be stacked together to fire in the same frame
requestAnimationFrame(long);
requestAnimationFrame(short);
Wednesday, August 25, 2021
 
Benji
answered 3 Months ago
69

I was able to fix this issue by making browser sleep for few seconds after every change in URL.

Below is the code snippet:

67 it('should create new job listing', function () {
68        //Login As Admin To Access Vacancies Feature
69        loginAsManager();
.
.        //load manager's dashboard list page
.        dashboardPage = new DashboardPage();
.        dashboardPage.vacanciesTab.click();
.
.        //load vacancies list page
.        var vacanciesUrl = browser.baseUrl + '#/vacancies';
.        browser.sleep(2000);
.        expect(browser.getCurrentUrl()).toEqual(vacanciesUrl);
.        vacanciesPage = new VacanciesPage();
.        vacanciesPage.addVacancyButton.click();
.
.

I don't think this is a neat solution to this problem.

I will be happy to hear, if someone has a better solution to this.

Cheers Gaurav

Friday, October 15, 2021
 
Morrison Chang
answered 2 Months ago
94

Maybe a dependency error. I'll suggest you to use a better practice for such lib.

  1. Put the fullcalendar scripts into vendor/assets/javascripts

  2. Require this script manually in application.js before the tree and after jquery and any other lib it depends.

    /=require 'fullcalendar`
    

Add

Check the loaded Javascript files in header, if application.js is the last, you have dependency error. The lib must be there before calling it.

Thursday, November 11, 2021
 
Yuriy Faktorovich
answered 3 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share