Zoffix m: say "!" R~ 10.base: 16 00:04
camelia rakudo-moar 04af57: OUTPUT«A!␤»
Zoffix Found a good use of `R` metaop :)
awwaiid I have a list of things and a predicate -- what's a good way to see if they all match the predicate? Would 'so is-prime(<2 5 7 17>.all)' be efficient, or is there a better lazy eval way? 00:08
Zoffix
.oO( premature optimization is the root of all evil )
00:09
awwaiid yeah yeah. I switched to a loop already 00:10
so nevermind :)
MasterDuke speaking of premature optimization i just read the transcript of an interview with Knuth, he's a fascinating guy 00:15
Zoffix He also said Perl 6 may have came in too late... Screw him, he's a traitor :P 00:17
tadzik a heathen! :P 00:28
awwaiid Knuth addressed Perl 6? 01:06
Zoffix awwaiid, not really. It was a talk about what languages make it or break it or something and he said the time when the languages comes around is important and said something along the lines of "Perl 6... is it too late? I don't know" 01:15
awwaiid ah 01:16
Zoffix: why you not in #perl6? check this out, gist.github.com/awwaiid/d55434447e...f2eff53313 01:17
Zoffix Too much traffic. 01:18
awwaiid ah
Zoffix So, I'm looking at 40 lines of code that replace 4 characters (.all) ? 01:19
:)
Also, you asked your original question here, in #perl6-dev, and now your comment in #perl6 is without context :) 01:20
awwaiid not that. The fun of a very core proof-of-concept of QuickCheck -- I'm looking into building something inspired by quickcheck and/or clojure/spec
Zoffix Oh never mind that comment is not about your thing
awwaiid yeah ... I didn't actually mean my earlier question in here :)
well it is technically about my thing in that loop, but that's not important overall :) 01:21
Zoffix I've no idea what quickcheck is
awwaiid Just thought you might like this idea
ahh
it is predicate / random testing. The idea is if you can generate inputs to a function at random and can assert some result of the function (like 'sort' outputs a list where the first element is the smallest), then you do a reasonable sample of inputs, that you can get some easy and declarative testing 01:22
generating inputs is fun in perl6 when you can inspect the signature and param types to start making them
quickcheck is a haskell lib that has been ported to a bunch of other langs 01:23
So after this basic probabilistic predicate assertion stuff, next is that WHEN you find a bad case you can then minimize it -- try to find the simplest input that defies the predicate
which I haven't gotten to yet of course 01:24
MasterDuke sounds like fuzzing 01:33
awwaiid It is like fuzzing yes, with expected outcomes. Very popular in Haskellville because they get a lot of free input generation through the types 01:34
for example, here in the xmonad test suite the authors declare that if you swap a window and then swap it back you get the original configuration. They leave it up to the quickcheck harness setup to generate some inputs to try that against. github.com/xmonad/xmonad/blob/mast...wap.hs#L13 01:37
Ends up magical is my understanding. But I haven't used it much myself, just read about it
geekosaur it's not really magical. for any type you can declare an instance of the typeclass Arbitrary that generates random values; you can use the typeclass machinery to help with that so in many cases the instance is just boilerplate (and there are packages that will auto-create instances using generics, iirc) 01:40
the StackSet is parameterized specifically so we can use QuickCheck with non-X11 types to test its behavior, then use the X11 types (which are actually the same but it can't tell) to run it 01:41
so you can have QC generate random StackSets, apply W.swap twice, and verify the result is the original StackSet 01:45
awwaiid indeed. In my current experiment I'm making a multi sub 'gen' that will dispatch based on the types, which will take the place of the typeclass Arbitrary
geekosaur note that you get to reuse the machinery for fields, so gen for something like StackSet just means calling gen on its elements and building a StackSet from them, and the elements in turn use gen on their elements, etc.
no. data StackSet i l a sid sd = StackSet { current :: !(Screen i l a sid sd); visible :: [Screen i l a sid sd]; hidden :: [Workspace i l a]; floating :: Map a RationalRect } 01:48
hm, I gues sin p6 that would be instance vars 01:49
`has` vars
awwaiid ya
I'm also looking at clojure/spec as a way to declare these things, kinda interesting 01:50
geekosaur (i = tag/workspace name, l = layout, a = window, sid = screen id, sd = screen detail. for testing you can make sd and l (), sid and a Int, i String) 01:51
Zoffix m: say +"70\x[308]93" 02:19
camelia rakudo-moar 04af57: OUTPUT«Cannot convert string to number: trailing characters after number in '7⏏0̈93' (indicated by ⏏)␤ in block <unit> at <tmp> line 1␤␤Actually thrown at:␤ in block <unit> at <tmp> line 1␤␤»
Zoffix m: say "70\x[308]93"
camelia rakudo-moar 04af57: OUTPUT«70̈93␤»
Zoffix Design question: Should the coercion to numeric ignore the diarhesis and give 7093? There's a couple of tickets that look easy to fix, once that decision is made. 02:20
jnthn, pmichaud, TimToady ^ if you have time
One thing we already ignore is surrounding whitespace; I'd think ignoring diahresis would make sense. 02:22
m: say +" 7093 "
camelia rakudo-moar 04af57: OUTPUT«7093␤»
Zoffix goes to bed; will read replies in the morning, if any
TimToady can argue it both ways, but thinks the situation won't arise all that often, and votes for whichever is faster 04:06
ShimmerFairy I'd lean towards no; as an example, what would someone expect +"0.3̅" to do? 3/10 or 1/3 ? In that example, I'd think failing would be better than choosing a behavior silently that may not be desired. 04:21
TimToady that would be a slightly stronger argument if .base-repeating put out that format... 04:27
but it's a point 04:28
ShimmerFairy yeah, I'm not suggesting it's very reasonable to expect core Perl 6 to make that into 1/3, just that it could theoretically happen (and that it's not all that farfetched). 04:29
I think what makes diacritics different from surrounding whitespace is that the presence of a diacritic likely indicates an extra meaning we can't possibly guess (on average), whereas surrounding whitespace doesn't. 04:30
geekosaur base should fail, an ecosystem module could extend it 04:33
ShimmerFairy I suppose that to me, diacritics in the middle of what should be a numeric value indicates either an additional meaning you have to handle yourself, or that your data is (paritally) garbage :)
geekosaur likewise fwiw 04:34
TimToady just wonders about someone trying to copy/paste something with incidental formatting, like strikeout 04:40
or underlining, because it was a fill-in-the-blank form 04:41
not that is likely to end up with composing underbars 04:42
*that that
but I could imagine an entry form that did it that way 04:43
otoh, .ords.chrs is not that hard for stripping composers 04:45
just that the programmer might not anticipate the need for such
ShimmerFairy Is there any guarantee that we could distinguish a purely "decorative" or "meaningless" diacritic from a "meaningful" one? That is, how can CORE be sure that an underlined number is never really some kind of super-rare notational thing? 04:47
TimToady ya pays yer money and takes yer choice... 04:48
sometimes you just lose...
so like I said, I can argue it both ways
the question here is whether the dwim is worth more on average than the wat 04:49
ShimmerFairy Right, I can see the pro argument being that at least our number system almost never uses any sort of "digit modifier" to indicate different meanings.
TimToady and I think at least you can say the wat is easy to explain 04:50
and we could conceivably special-case overbar 04:51
but again, I'd like to know whether one way was slower than the other 04:52
programs spend a lot of time converting strings to numbers and back
ShimmerFairy My inclination is that this situation isn't very common at all, so I'd need to see some concrete examples of why auto-diacritic-stripping would be helpful to have in CORE.
TimToady well, it might just be free, given how nqp::ordat works 04:53
ShimmerFairy I imagine the extra steps would _technically_ lead to more execution time, but I'm not certain it would be significantly so. 04:54
TimToady what extra steps? 04:55
ShimmerFairy TimToady: just the extra statements to ordat and so on. 04:56
TimToady it might well be that rejecting synthetics outright could be faster 05:00
[Tux] This is Rakudo version 2016.08.1-163-g04af57c built on MoarVM version 2016.08-43-g3d04391 06:10
csv-ip5xs 8.988
test 16.534
test-t 7.089
csv-parser 17.076
cognominal Vendredi les décodeurs du monde nous parlent d'intox sur la santé de Clinton et le lundi de sa pneumonie :) Malade, peut-etre à cause d'un baril de chlore laché par Assad, ca expliquerait tout :) 06:57
nine ?? 07:00
cognominal oops; wrong channel 07:02
lizmat it does explain everything :-) 07:05
dalek ast: c7dd8f0 | niner++ | S10-packages/precompilation.t:
Test if we pick up changes of a precompiled dependency's source file.
07:11
nine I can bring back the speedup reverted in commit 376b5f4ee210f36d1ec3d683592901705955604b. 07:15
But it would still not pick up changes done by --force installation of a module if the precomp file lives in a precomp store further up the chain.
Thing is, that we intended a short-name:ver:auth triplet to be unique and distros to be immutable from the very beginning. The optimization would rely on that. 07:16
I'm inclined to just give it a try and force people to adapt by increasing version numbers instead of --force installing. 07:18
What do you think?
lizmat I agree with you 07:22
dalek kudo/nom: c170ebe | niner++ | src/core/CompUnit/PrecompilationRepository.pm:
Speed up loading deps by only running .modified checks when needed

  $*REPO.id represents the contents of all repositories. We already check if
that changed since we precompiled a module. If it is still the same, there should be no reason to check the .modified of the source file. If it changed, we need to check it as a change in our source file could be exactly what caused the different checksum. Note that this relies on the immutability of installed distros which we haven't enforced so far. Brings GTK::Simple's load time back down to 227ms.
07:25
nine lizmat: ok, so let's give it a try :) 07:26
dalek kudo/nom: 512b5e2 | lizmat++ | src/core/Rakudo/Internals.pm:
Introducing Rakudo::Internals.SeqFromSeqs

Create a Seq from a Seq of Seqs. Also tune ListsFromSeq so it can handle empty List objects without $!reified
07:50
kudo/nom: 1379175 | lizmat++ | src/core/List.pm:
Make List.combinations about 4x faster

  - based on "my @a = <a b c d>; for ^500 { my @b = @a.combinations }"
  - using the new SeqFromSeqs functionality
  - create separate candidate for the combinations() case
[Coke] Zoffix: I had a todo from ages ago that may be of interest to you: - update rakudo release announcement to solicit donations to the Perl 6 Core Dev Fund 08:46
DrForr You too can emulate Jimmy Wales :) 08:48
lizmat nine: t/spec/S10-packages/precompilation.t has become flappy for me 09:25
either test 47 fails, or 48, or all tests, or 4 other tests :-(
(so far)
hmmm... seems 47 and 48 are alternating on subsequent runs 09:26
some cleanup issue ?
stmuk_ [Coke]: putting a Begging Letter in R* could be a good idea as well 09:29
does anyone know of any copy which could be reused? (just looking on the Perl Foundation site) 09:30
arnsholt Do we have anyone working semi-regularly on NQP or Rakudo on JVM? 10:04
Zoffix psch used to, but I haven't seen them in a while. 10:06
.seen psch
yoleaux2 I saw psch 4 Aug 2016 16:20Z in #perl6-dev: <psch> i mean, we probably could have infix:sym<.=> do a similar check to methodop, the latter being where we throw that error
Zoffix NeuralAnomaly, stats
NeuralAnomaly Zoffix, [✘] Next release will be in 4 days and 18 hours. Since last release, there are 48 new still-open tickets (0 unreviewed and 0 blockers) and 10 unreviewed commits. See perl6.fail/release/stats for details
Zoffix 🎺🎺🎺 REMINDER: The next Rakudo release will be this Saturday. Please review the ChangeLog to ensure the changes you made have been logged properly. 10:07
New blog post "Perl 6 Core Hacking: Grammatical Babble": perl6.party/post/Perl-6-Core-Hackin...cal-Babble
nine lizmat: right now precompilation.t fails 2 tests consistently on my laptop. But reverting my optimization doesn't change that :/ 10:19
lizmat hmmm... :-( 10:20
nine lizmat: oh wait a sec. Those two failing tests should be TODOed. The test harness doesn't seem to understand that. 10:26
Or rather the Test module doesn't output the TODO markers 10:29
Despite the line reading: todo('no 6model parametrics interning yet'); is_run
Zoffix works fine here 10:31
Just built from HEAD. Passes fine with and without PERL6_TEST_DIE_ON_FAIL turned on: gist.github.com/zoffixznet/fedf091...0642a29e67 10:36
nine Well maybe I should have run precompilation.rakudo.moar instead of precompilation.t... 10:42
Zoffix :) 10:45
nine lizmat: so far I've only once managed to get precompilation.rakudo.moar to fail due to "duplicate definition of symbol Test" 10:47
lizmat: RAKUDO_MODULE_DEBUG output may help
lizmat nine: will try in a mo 10:54
dalek kudo/nom: 3c2451c | lizmat++ | src/core/List.pm:
Make combinations(n,k) about 1.8x faster

  - rewrite using nqp ops
  - no JVM dependent code necessary anymore
  - don't use return for successful find
11:13
kudo/nom: 9d1a086 | lizmat++ | docs/ChangeLog:
Mention the combinations improvements
11:15
lizmat Method 'version' not found for invocant of class 'Needed' 11:16
in block <unit> at -e line 3
nine ^^^ 11:17
getting that consistently now
siesta& 11:18
nine lizmat: t/spec/S10-packages/precompilation.t:260 should overwrite t/spec/packages/RT128156/Needed.pm6 with a version that contains the "version" method 11:19
lizmat: can you confirm that it does so (it gets reverted in line 265)? Does by any chance adding a sleep 2; after that spurt help? 11:20
lizmat: now that I thought some more, the sleep should probably be before the spurt as we need to see a difference between the outdated precomp file's .modified and the source. Probably safest to add it before and after though. 11:42
[Coke] I could really use a new docker image based on the 2016.09 release (coming soon) 12:00
Willing to offer a 2-beer bounty. :) 12:01
P6M Merging GLOBAL symbols failed: duplicate definition of symbol Test 13:57
[Coke] does a realclean
dalek ast: 3ceb078 | coke++ | S07-iterators/range-iterator.t:
fudge for moar
14:08
kudo/nom: 15532db | coke++ | t/spectest.data:
run these (fudged) tests
nine [Coke]: when exactly did you get that error? 14:10
ugexe should we start pushing for distribution names to use `-` instead of `::` as a separator? 14:13
[Coke] should this test file be deleted? It's not run: S03-operators/shortcuts.t
nine: during a 'prove -v -e t/fudgeandrun /path/to/file' - went away with a realclean/rebuild. (was in a build directory) 14:14
[Coke] opens a ticket. 14:15
github.com/perl6/roast/issues/157 14:17
MasterDuke_ jnthn: hello hello hello. have you had any chance to think about github.com/rakudo/rakudo/pull/859? this is the fix that "quietly" does union hyperoperators for hashes 14:38
lizmat back from siesta 14:59
nine: looks like putting a sleep before/after does fix the issue
shall I commit it ?
dalek ast: 4585a9c | lizmat++ | S10-packages/precompilation.t:
Add some rest to make for less flappy testing
15:27
|Tux| This is Rakudo version 2016.08.1-169-g15532db built on MoarVM version 2016.08-43-g3d04391 15:29
csv-ip5xs 9.015
test 15.223
test-t 6.787
csv-parser 17.359
MetaZoffix \o/
[Coke] nice. 15:30
timotimo very not bad 15:32
monada MasterDuke: I see this comment: irclog.perlgeek.de/perl6-dev/2016-0...i_13192789 was jnthn++ having concerns about github.com/rakudo/rakudo/pull/859 ? I think it's OK to merge, but wanted to check first. 17:53
nine lizmat: yes please. As the test is about time stamps, a sleep does seem like an appropriate fix 17:57
Those other spurious errors worry me :/ 18:06
A kinda ironic detail: the CORE dist is always installed as version 6.c violating our own rule. 18:09
jnthn MasterDuke_: Sorry, was tied up with $other-job and just reading backlog here now. :) 18:12
yoleaux2 11 Sep 2016 03:28Z <Zoffix> jnthn: would you add what 'async-socket-str-fixes' brought in to the ChangeLog? I've no idea.
jnthn MasterDuke_: The main concern is if there's any lazy evaluation taking place and we could swallow the warnings associated with that. But since it's Associative, I guess not. 18:13
MasterDuke_: The safe fix would be `my &quiet-op = -> |c { quietly op(|c) }` 18:14
MasterDuke_: Which of course comes at quite a cost because of the extra invocation and args shuffling 18:15
otoh I guess if we were to assume it's a binary op we can do it much cheaper
But that'd make sure only the evaluation of the op is quieted
To show up in this case we'd need somebody to have a custom Associative implementation that could warn when indexed though, which is kinda marginal 18:16
So this is more of an issue for a similar patch for hyper on Positional, where laziness (and so suppressing warnings at a distance) really is a possibility.
dalek ast: eedf53d | usev6++ | S17-supply/interval.t:
Fudge (skip) test using Proc::Async for JVM
18:27
ast: 2a5e743 | usev6++ | S17-supply/interval.t:
Fix fudging for JVM
18:29
kudo/nom: a9ed671 | TimToady++ | src/Perl6/Grammar.nqp:
desigilname var checked too soon in quotes

When parsing quotes, interpolated variables with multiple sigils were being checked immediately, but that violates the constraint that backtrackable interpolations should not have side effects. We now delay that variable check out to where normal variables are checked, after any such backtracking would be triggered.
Fixes RT #129257.
18:41
synopsebot6 Link: rt.perl.org/rt3//Public/Bug/Displa...?id=129257
MasterDuke_ jnthn: yeah, Positional seems a thornier problem. and like Zoffix said in his comment on th PR, you can't really know what to replace an undefined with. so the impression i'm getting is that this is good to merge? 19:36
dalek kudo/nom: 804bf67 | (Zoffix Znet)++ | / (3 files):
Fix NativeCall CArray hanging when created from empty list

The issue was we were calling nextsame when @values was empty, but the nextsame candidate was the one with a slurpy, that called the @values candidate again, resulting in a loop.
Instead of having a separate multi for empty argument case, we return its value when the @values is empty, resolving the infiniloop.
Fixes RT#129256: rt.perl.org/Ticket/Display.html?id=129256
19:49
synopsebot6 Link: rt.perl.org/rt3//Public/Bug/Displa...?id=129256
dogbert17 Zoffix: I've made the change locally in a branch, done some cmdline testing and then 'make spectest'. However, there were failures ... 20:05
failures in t/spec/S32-io/socket-accept-and-working-threads.t and t/spec/S32-num/power.rakudo.moar 20:06
t/spec/S32-num/power.rakudo.moar .................................. Dubious, test returned 1 (wstat 256, 0x100) 20:07
ZoffixMobile dogbert17, that sounds like you aren't roast HEAD. 20:10
did you start from a fresh checkout of rakudo?
dogbert17 yes
ZoffixMobile Weird. Did you already commit the change? Can I see it? 20:11
dogbert17 when I wrote make spectest, roast was automatically downloaded
haven't committed yet, wanted to ask about the failures first (otoh, I did the change you suggested) 20:12
ZoffixMobile can you pastebin output of git diff
dogbert17 gist.github.com/dogbert17/f0bac4e0...bccec05a26 20:14
ZoffixMobile Yeah, that's good. Submit that as PR, I spectested that before I headed out and it was clean so the failures aren't due to this change. I'm unsure why you have spectest failures. Some tests flop sometimes, so you can try running the spectest again. Both of those recently had failures (but were then fixed), which is why I thought you may have been running an older spectest 20:17
dogbert17 ok, I'll commit and send a PR 20:18
jnthn MasterDuke: I think so, but we should consider the Positional case also 20:20
dalek kudo/nom: 6fc1d9b | jnthn++ | docs/ChangeLog:
Explain IO::Socket::Async fixes in ChangeLog.
20:23
dogbert17 Zoffix: done (I think) 20:27
dalek kudo/nom: 59ce05e | (Jan-Olof Hendig)++ | src/core/Cool.pm:
Make Cool.trans work the same as Str.trans

Cool.trans coerces the invovant to Str and then directly calls Str.trans. The way this is done causes adverbs, if specified, to be thrown away. We must ensure that the these parameters are sent to Str.trans and not being thrown away. A couple of changes suggested by Zoffix++ takes care of this problem.
20:32
kudo/nom: 22946ed | lizmat++ | src/core/Cool.pm:
Merge pull request #877 from dogbert17/fix-rt-129258

Make Cool.trans work the same as Str.trans
dogbert17 wohoo 20:34
nine dogbert17: your branch was probably not up to date with rakudo nom or you missed running config.status. Those failures are because of an out of date nqp/moarvm 20:35
dogbert17 nine: I probably missed something. Both nqp and moarvm were downloaded when I typed 'perl Configure.pl --gen-moar --gen-nqp --backends=moar' 20:37
ZoffixMobile dogbert17, ah, but your rakudo fork may have been out of date 20:41
git pull https//github.org/rakudo/rakudo
Anyway, dogbert17++ Achievement Unlocked: Fix Rakudo Bug :) 20:42
nine dogbert17: rakudo will build the nqp and moar that was required at the time of that rakudo version. roast may already test fixes in newer version.
dogbert17 When I forked and cloned, the last fix included was 'desigilname var checked too soon in quotes' by TimToady 20:44
nine odd 20:45
dogbert17 not all socket async tests failed, only five of them 20:46
Also, I'm running a 32 bit vm if that makes a difference
nine That could actually be a deciding factor 20:48
Few people run rakudo on 32 bit systems. It's much less well tested there.
dogbert17 is 32 bit officially supported? 20:49
ZoffixMobile I think our "officially supported" is constrained by whether or not there are volunteers to provide support on the platform in question :) 20:52
I use it on a 32bit box at $work. Seems to work fine
Zoffix dogbert17, will you submit roast tests for that bug as well? 21:07
dogbert17++ # making me more aware of what Core Hacking blogs need to be written :) 21:13
dalek ast: a2e54a7 | (Zoffix Znet)++ | S02-literals/string-interpolation.t:
%%, @@, and && do not attempt to interpolate any variables

RT#129257: rt.perl.org/Ticket/Display.html?id=129257
21:26
synopsebot6 Link: rt.perl.org/rt3//Public/Bug/Displa...?id=129257
timotimo m: my $foo; say "$foo.say().notamethod" 21:27
camelia rakudo-moar 22946e: OUTPUT«(Any)␤True.notamethod␤»
timotimo m: my $foo; say "$foo.say().notamethod()"
camelia rakudo-moar 22946e: OUTPUT«(Any)␤Method 'notamethod' not found for invocant of class 'Bool'␤ in block <unit> at <tmp> line 1␤␤»
timotimo hm
Zoffix m: my $foo; say "$foo.say.notamethod()"
camelia rakudo-moar 22946e: OUTPUT«(Any)␤Method 'notamethod' not found for invocant of class 'Bool'␤ in block <unit> at <tmp> line 1␤␤»
Zoffix Looks good to me
timotimo i seem to recall i had some issue at some point 21:28
Zoffix The Unguided is such a good band to hack while listening to \o/ www.youtube.com/watch?v=1ZNhfeIcArE 21:31
dalek ast: 0cbc5bf | (Zoffix Znet)++ | S05-transliteration/trans.t:
Remove trailing whitespace
21:43
ast: 54ad7fd | (Zoffix Znet)++ | S05-transliteration/trans.t:
Adverbs on Cool.trans work the same as on Str.trans

RT#129258: rt.perl.org/Ticket/Display.html?id=129258
21:45
synopsebot6 Link: rt.perl.org/rt3//Public/Bug/Displa...?id=129258
Zoffix dogbert17, I added the tests in github.com/perl6/roast/commit/54ad7fda46 Teamwork ✋
lizmat and another Perl 6 Weekly hits the Net: p6weekly.wordpress.com/2016/09/12/...-youtuben/ 22:12
jnthn lizmat++ 22:16
A nice bedtime read 22:17
'night, #perl6
*-dev :)
lizmat gnight jnthn
lizmat also calls it a night
timotimo gnite lizmat and jnthn 22:18
Zoffix lizmat++ # good weekly 22:23
timotimo Zoffix++ # good week 22:24
Zoffix m: say ^∞ ~~ ∞ 22:41
camelia rakudo-moar 22946e: OUTPUT«True␤»
Zoffix m: say ^4 ~~ 4
camelia rakudo-moar 22946e: OUTPUT«True␤»
Zoffix huh
m: say ^4 ~~ 3
camelia rakudo-moar 22946e: OUTPUT«False␤»
Zoffix oh, it's using .elems ... I thought it'd say whether it's in range 22:42
timotimo yeah, that would be the other way around
Zoffix m: say 3 ~~ ^4
camelia rakudo-moar 22946e: OUTPUT«True␤»
Zoffix m: say ∞ ~~ ^∞
camelia rakudo-moar 22946e: OUTPUT«False␤»
Zoffix timotimo++ cheers